2012-02-13 7 views
0

開いている汎用階層を持つオブジェクトの階層を平坦化したい。階層内の選択されたノードを再帰とジェネリックで削除する

このリンクRecursive List Flattening

は、渡されたのIEnumerableを取っていることを行う方法を示しています。しかし、私は渡されたオブジェクトTを平らにしたいと思います。

その子は一般的で再帰的なやり方です。

U1.Children(U2,U3,U4) 
U2.Children(U9,U10) 
U3.Children(U11,U12) 
U4.Children(U20,U30) 

私は方法U1(選択されたノード)に渡すと、私はこのフラットなリストを取得したい:

U1,U2,U3,U4,U9,U10,U11,U12,U20,U30 

は、一般的な方法で何とか可能ということですか?

答えて

2

コンパイラはオブジェクトがそのpropertylを持っていることを知っている必要があります:

public static IEnumerable<T> Flatten<T>(this T root, Func<T, IEnumerable<T>> getChildren) 
{ 
    IEnumerable<T> rootSingleton = new T[] { root }; 
    IEnumerable<T> children = getChildren(root); 
    IEnumerable<T> descendants = children.SelectMany(child => Flatten(child, getChildren)); 
    return rootSingleton.Concat(descendants); 
} 

を次に、あなたはとてもようにそれを消費することができます:

var flat = u1.Flatten(u => u.Children); 
0

ごhierarcyは、あなたが使用する可能性のある唯一のレベルの深さであれば組合

public IEnumerable<T> Flattern<T>(IEnumerable<T> input) where T : ISomeinterface { 
    return input.SelectMany(t=> t.Children).Union(input) 
} 

と多くを選択さて、このコードは、あなたがChildren性質を持っているいくつかの基本クラスまたはインタフェースとそれを制約ますunessをコンパイルしません。あなたが子供を取得するための機能を受け入れ、再帰的な拡張メソッド定義することができ

+0

nah ...入力はIEnumerable ではなく、Childrenプロパティを持つTである必要があります。私のサンプルを見てください。 – Pascal

関連する問題