2017-02-10 16 views
1

私は、オブジェクトのリストを持つオブジェクトのリストを持つモデルを持っています。に。私がしようとしているのは、良い方法で、すべての子オブジェクトの数を得ることです。Linqのすべての子リスト、孫リスト、孫孫リストなどのカウントを取得する方法

私は、次の例を設定している:

これは私のモデルである:

public class Model 
{ 
    public List<GrandParent> GrandParents { get; set; } 
} 

そして、これらは私のオブジェクトである:ここでは

public class GrandParent 
{ 
    public string Name { get; set; } 
    public List<Parent> Parents { get; set; } 
} 

public class Parent 
{ 
    public string Name { get; set; } 
    public List<Child> Children { get; set; } 
} 

public class Child 
{ 
    public string Name { get; set; } 
    public List<Friend> Friends { get; set; } 
} 

public class Friend 
{ 
    public string Name { get; set; } 
} 

は、私がコンソールに持っている設定ですアプリ:

static void Main(string[] args) 
    { 
     var friendOne = new Friend { Name = "Friend 1" }; 
     var childOne = new Child { Name = "Child 1", Friends = new List<Friend>() }; 
     var childTwo = new Child { Name = "Child 2", Friends = new List<Friend> { friendOne } }; 
     var parentOne = new Parent { Name = "Parent 1", Children = new List<Child> { childOne, childTwo } }; 
     var grandParentOne = new GrandParent { Name = "GrandParent 1", Parents = new List<Parent> { parentOne } }; 

     var model = new Model { GrandParents = new List<GrandParent> { grandParentOne } }; 

     var count = model.GrandParents.Count + 
      model.GrandParents 
       .Sum(gp => gp.Parents.Count + gp.Parents 
       .Sum(p => p.Children.Count + p.Children 
       .Sum(c => c.Friends.Count))); 

     Console.WriteLine(count); 
     Console.ReadLine(); 
    } 

私は私のカウント変数が私に与えている5つのオブジェクト(1人の友人、2人の子供、1人の親と1人の祖父母)を持っています。しかし、私は私のlinqクエリでそれをやっている方法が好きではない、これを行うためのより良い/クリーンな方法がありますか?

+0

あなたは作業コードを持っています。それはhttp://codereview.stackexchange.com/の質問です。 –

+2

「GrandParents」、「Parents」などには別のクラスが必要ですか?あなたが 'List Relatives'を持つ' Person'のようなタイプを1つだけ持つことができるならば、短い再帰的な方法を作ることができます。しかし、それはあなたが「より良い/きれいな」とみなすものではないかもしれません。 –

+0

@RenéVogtはい、異なるクラスを持つ必要がありますが、これは単なる例です。 – Viqas

答えて

2

コメントに記載されているように、1つの方法は、ツリー内のすべてのノードに同じオブジェクトを使用し、何かを再帰的に書くことです。

これらのオブジェクトを保持したい場合、別の方法として、すべてが子孫を数える方法以上のことを知らないインターフェースを実装することになります。

public interface IHasDescendents 
{ 
    int CountOfDescendents(); 
} 

すべてのクラスのそのインターフェイスを実装することにより、あなたのコードは単純に私はあなたが詳細を実装することができ疑うが、ちょうどコメントしていない場合、私はどのようにあなたを紹介します

var count = model.GrandParents.Sum(gp => 1 + gp.CountOfDescendents()); 

だろう。

+0

私はむしろ、オブジェクトの数を得るための具体的なメソッドを書いていません。実際にテストアサーションに必要なこのカウントは、テストの実装を変更したくないということです。 – Viqas

+0

@Viqas huh?だから、あなたは何も変更する必要はありません魔法のソリューションが欲しいです。 OK。がんばろう。ところで、明示的にインターフェイスを実装してクラス自体には表示されないようにすることもできますが、テストはアサーションのためにインターフェイスにキャストできます。 – Jamiec

+0

@Viqasまたは、子孫を数える方法を知っているテストのためだけに使用されるラッパー構造体を記述します。 – Jamiec