2009-12-30 4 views
0

У меня есть метод (показано ниже), который я обнаружил, может быть повторно использован в коде в другом месте, если я могу превратить его в общий метод, но я борюсь с синтаксисом и могу использовать немного помощи:Переписать тип конкретного метода как общий

Пример:

private List<IndexEntry> AddParentReferences(List<IndexEntry> listWithoutParents) 
     { 
      List<IndexEntry> listWithParents = new List<IndexEntry>(); 

      foreach (IndexEntry currentEntry in listWithoutParents) 
      { 
       if (currentEntry.SubEntries == null || currentEntry.SubEntries.Count < 1) 
       { 
        listWithParents.Add(currentEntry); 
        continue; 
       } 
       AddIndividualParentReference(currentEntry); 
       listWithParents.Add(currentEntry); 
      } 
      return listWithParents; 
     } 

Как вы можете видеть, что это простой метод, который принимает в списке типов IndexEntry и перечисляет этот список, добавив ссылки на родительские элементы в иерархии. Я обнаружил, что существуют аналогично разработанные типы, которым также понадобится такая ссылка, добавленная в разных точках. Я хотел бы изменить этот код, чтобы взять список и вернуть соответствующий список, где T - это тип, который был передан. Это казалось прямым методом для записи, но я думаю, что я могу пропустить простую проблему sytax в моем методе определение. Может ли кто-нибудь просветить меня?

Спасибо заранее,

Стива

+0

Можете ли вы добавить информацию о методе AddIndividualParentReference? Я этого не вижу. –

+0

Добавить после имени функции в объявлении: private Список AddParentReferences (Список listWithoutParents) ---- Вы можете захотеть реорганизовать это имя на 'TElement' для удобства чтения. –

ответ

5

Когда вы делаете метод родовым, вам необходимо добавить ограничение типа. Если вы этого не сделаете, вы не сможете получить доступ к currentEntry.SubEntries, поскольку компилятор не может сделать вывод, что у T есть такое свойство. Таким образом, определить тип интерфейса, как я сделал ниже, а затем действуйте следующим образом:

List<T> AddParentReferences<T>(List<T> listWithoutParents) where T : IIndexEntry { 
    List<T> listWithParents = new List<T>(); 

    foreach (T currentEntry in listWithoutParents) { 
     if (currentEntry.SubEntries == null || currentEntry.SubEntries.Count < 1) { 
      listWithParents.Add(currentEntry); 
      continue; 
     } 
     AddIndividualParentReference(currentEntry); 
     listWithParents.Add(currentEntry); 
    } 
    return listWithParents; 
} 

Вот минимальный интерфейс вам нужно будет сделать выше работы:

interface IIndexEntry { 
    IList<IIndexEntry> SubEntries; 
} 
+1

Спасибо ... это заставило меня пойти туда, где мне нужно. –

3

Вы можете сделать метод, добавив <T> к имени метода.

Проблема в том, что вам требуется T, имея SubEntries. Вы можете решить эту проблему путем ограничения T типов, которые реализуют интерфейс (см @ ответ Ясона), или путем передачи в предикате, который говорит, является ли запись пустой или нет:

private List<T> AddParentReferences<T>(
    List<T> listWithoutParents, 
    Func<T, bool> isEmpty) 
{ 
    List<T> listWithParents = new List<T>(); 
    foreach (T currentEntry in listWithoutParents) 
    { 
     if (isEmpty(currentEntry)) 
     { 
      listWithParents.Add(currentEntry); 
      continue; 
     } 
     AddIndividualParentReference(currentEntry); 
     listWithParents.Add(currentEntry); 
    } 
    return listWithParents; 
} 

Использование:

AddParentReferences<IndexEntry>(
    indexEntries, 
    e => e.SubEntries == null || e.SubEntries.Count < 1);