2009-12-30 5 views
0

J'ai une méthode (montrée ci-dessous) que j'ai découverte peut être réutilisée dans le code ailleurs si je pouvais la transformer en une méthode générique, mais je suis aux prises avec la syntaxe et je pourrais utiliser un peu d'aide:Réécrire la méthode spécifique de type générique

Exemple:

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; 
     } 

Comme vous pouvez le voir est une méthode simple qui prend dans une liste des types indexentry et énumère cette liste en ajoutant des références à des éléments de parent dans la hiérarchie. J'ai découvert qu'il existe des types conçus de manière similaire qui auront également besoin de ce type de référence ajouté à divers points. Je voudrais modifier ce code pour entrer dans une liste et retourner une liste appropriée où T est le type transmis. Cela a semblé être une méthode simple à écrire, mais je pense qu'il me manque un problème de syntaxe simple dans ma méthode définition. Quelqu'un peut-il m'éclairer?

Merci à l'avance,

Steve

+0

Pouvez-vous ajouter des informations sur la méthode AddIndividualParentReference? Je ne le vois pas. –

+0

Ajoutez après le nom de la fonction dans la déclaration: private Liste AddParentReferences (Liste listWithoutParents) ---- Vous pouvez refactoriser ce nom à 'TElement' pour plus de lisibilité. –

Répondre

5

Lorsque vous prenez la méthode générique, vous devez ajouter une contrainte de type. Si vous ne le faites pas, vous ne pouvez pas accéder à currentEntry.SubEntries car le compilateur ne peut pas en déduire que T possède une telle propriété. Ainsi, définir un type d'interface comme je l'ai fait ci-dessous, puis procéder comme ceci:

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; 
} 

Voici l'interface minimale, vous devrez faire le travail ci-dessus:

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

Merci ... cela m'a permis d'aller là où je devais être. –

3

Vous pouvez faire la méthode générique en ajoutant <T> au nom de la méthode. Un problème est que vous avez besoin de T en ayant une propriété SubEntries. Vous pouvez résoudre ce problème en limitant T aux types qui mettent en œuvre une interface (voir @ réponse de jason), ou en passant dans un prédicat qui indique si une entrée est vide ou non:

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; 
} 

Utilisation:

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