2017-10-13 2 views
1

Ich möchte eine Linq-ähnliche Erweiterungsmethode erstellen, um alle Elemente aus einer hierarchischen Struktur wie eine Struktur zu erhalten.Verwenden Sie verschachtelte Generika ohne viel Code

das ist meine Erweiterung

public static List<T> GetAllRecursive<T, TU>(this IList<T> list, Func<T, TU> func) where TU : IEnumerable<T> { 
     var allList = new List<T>(); 
     var toAdd = list.ToList(); 
     while(true) { 
      allList.AddRange(toAdd); 
      var childs = toAdd.SelectMany(x => func(x)).ToList(); 
      if(childs.Count == 0) { 
       return allList; 
      } 
      toAdd = childs; 
     } 
    } 

Ich nenne es wie dieses

var allGuidelines = Guidelines.GetAllRecursive(x => (IEnumerable<MachineGuidelineTreeItemViewModel>)x.Children);

Wie kann ich diese Methode zu verbessern, so brauche ich nicht jedes Mal wenn ich diese verwenden zu werfen?

Vielen Dank im Voraus

+0

Was ist der Rückgabetyp von Kindern? –

+0

und warum müssen Sie es überhaupt in IEnumerable umwandeln? Ist x.Children nicht bereits IEnumerable <>? Ist es ein generischer Typ, zum Beispiel IEnumerable oder etwas ähnliches? Wenn ja, woher weißt du, dass es sicher ist, es in den IE zu übertragen? – quetzalcoatl

+0

Children ist eine BindableCollection horotab

Antwort

1

Sie TU Typ-Parameter entfernen, und verwenden Sie OfType auf IEnumerable statt:

public static List<T> GetAllRecursive<T>(this IList<T> list, Func<T, IEnumerable> func) { 
    var allList = new List<T>(); 
    var toAdd = list.ToList(); 
    while(true) { 
     allList.AddRange(toAdd); 
     var childs = toAdd.SelectMany(x => func(x).OfType<T>()).ToList(); 
     if(childs.Count == 0) { 
      return allList; 
     } 
     toAdd = childs; 
    } 
} 

Dieser Ansatz milderen ist, weil es Ihnen Funktionen können übergeben, die eine gemischte Tüte zurückkehren von Elementen, wobei die Methode nach Typ gefiltert wird.

+0

Ich denke, dass die Variable 'toAdd' und die Variable' childs', die erforderlich sind, nicht notwendigerweise 'List's sein müssen. Wahrscheinlich macht das keinen großen Unterschied, aber ich denke, dass es möglich ist, 'ToList()' zu vermeiden, wenn 'childs' zugewiesen wird ... – BurnsBA

+1

@BurnsBA Ich stimme zu, es gibt definitiv einen Platz, um diese Methode noch weiter zu machen Allgemeines. Ich bin mit der Implementierung von OP gegangen, um einen spezifischen Mangel zu beheben, während ich den Rest seines Codes beibehalten habe. – dasblinkenlight

+0

das ist genau das, was ich gesucht habe jetzt habe ich einen kleinen Aufruf: 'var allGuidelines = Guidelines.GetAllRecursive (x => x.Children);' - Danke – horotab

Verwandte Themen