2017-06-27 9 views
0

私のアプリケーションでは、enumプロパティを持つオブジェクトのリストがあります。クラスをもっと使いやすくするために、enumプロパティに基づいて、これらのオブジェクトの特定のサブジェクトを返すリストを追加することにしました。他のリストプロパティのサブセットを返しますが、変更可能なリストプロパティ

私はこのサブセットにオブジェクトを追加すると、メインリストを更新しないという問題があります。

これは可能ですか?

public class foo 
{ 
    public int Id { get; set; } 
    public string Description { get; set; } 
    public List<bar> bars { get; set; } 

    //list of only bars of barType one 
    public List<bar_one> bar_ones 
    { 
     get 
     { 
      return (this.bars.Where(x => x.barType == barType.one)).ToList().Cast<bar_one>().ToList(); 
     } 
    } 

    public foo() 
    { 
     this.bars = new List<bar>(); 
    } 
} 

public class bar 
{ 
    public bar() { } 
    public bar(barType bt) { 
     this.barType = bt; 
    } 

    public int Id { get; set; } 
    public string Description { get; set; } 
    public barType barType { get; set; } 
} 

public class bar_one : bar 
{ 
    public bar_one() : base(barType.one) { } 
} 

public enum barType 
{ 
    one, 
    two, 
    three 
} 


public static void Main() 
{ 
    foo f = new foo(); 
    f.bars.Add(new bar { Id = 1, Description = "b1", barType = barType.one }); 
    f.bars.Add(new bar { Id = 2, Description = "b2", barType = barType.two }); 

    //this does not break, but the amount of objects in f.bars remain the same. 
    f.bar_ones.Add(new bar_one { Id= 3, Description="b1_2" }); 
} 
+0

は、あなたが本当にbar_ones' 'にバーを追加できるようにする必要がありますか?代わりに 'bar'プロパティにそれらを追加するだけでいいのですか? –

+0

本当にこの振る舞いが必要な場合は、バーリストをラップし、そこから特定のバータイプをフィルタリングするカスタムコレクションタイプを作成する必要があると思います。また、内部メソッドにAddメソッドを委譲します。 –

+0

@AndreasZita、私は(それは以前のデザインの一部だった)が、この方法はきれいで使いやすいと思った。 –

答えて

1

bar_onebarから派生として、あなたはまた、元のリストbarsに項目を追加することができます。それは、リストの項目を抽出することができますようにあなたがbar_onesの実装を変更する必要があり、誤解を避けるために

f.bar.Add(new bar_one { Id= 3, Description="b1_2" }); 

タイプbar_oneですが、追加することはできません。 IEnumerable<bar_one>代わりのIList<bar_one>使用して:また

public IEnumerable<bar_one> bar_ones 
{ 
    get 
    { 
     return this.bars.OfType<bar_one>(); 
    } 
} 

を、私はあなたが本当にクラスbar_onebarType列挙を必要とするかどうかを考えることを提案したいです。現在の方法では、それぞれbarTypeの列挙型とクラスの両方があります。新しいタイプの場合は、両方を作成する必要があります。

一方的な方法で決定する方が良いでしょう。列挙型を持たないクラス階層しか持たない(これはOODの観点から優れている)。

0

あなたは変更する必要があります。

public List<bar_one> bar_ones 
{ 
    get 
    { 
     return (this.bars.Where(x => x.barType == barType.one)).ToList().Cast<bar_one>().ToList(); 
    } 
} 

に:

IEnumerable<bar_one> bar_ones 
{ 
    get 
    { 
     return this.bars.Where(x => x.barType == barType.one).Cast<bar_one>(); 
    } 
} 

をその後、むしろあなたがbarsにそれらを追加する必要がありbar_onesにエントリを追加するよりも。これは自動的にbar_onesに反映されます。その後のAddは(一時的にしか存在していること)barsリストに、間違ったリストに新しいbar_oneを追加しないように、あなたは新しいリストを作成ToList()を使用することにより

+0

それは@AtronSeigeを助けましたか? – mjwills

0

あなたが本当にサブセットをしたい場合は、これはあなたがそれを行うことができる方法(基本例)である。

public class Subset<T> : ICollection<T> 
    { 
    private readonly IList list_; 
    public Subset(IList list) { list_ = list; } 
    public IEnumerator<T> GetEnumerator() => list_.OfType<T>().GetEnumerator(); 
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 
    public void Add(T item) => list_.Add(item); 
    public void Clear() => list_.Clear(); 
    public bool Contains(T item) => list_.Contains(item); 
    public void CopyTo(T[] array, int arrayIndex) => list_.CopyTo(array, arrayIndex); 
    public int Count => list_.Count; 
    public bool IsReadOnly => list_.IsReadOnly; 
    public bool Remove(T item) { list_.Remove(item); return true; } 
    } 
関連する問題