2017-06-27 53 views
0

在我的应用程序中,我有一个具有枚举属性的对象列表。为了让这个类稍微更友好一点,我决定添加一个列表,根据它们的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'?为什么不把它们添加到'bars'属性呢? –

+0

如果你真的想要这种行为,我认为你需要创建一个自定义的集合类型来包装你的酒吧列表,并从中过滤出一个特定的酒吧类型,并且还将一个添加方法委托给你的内部列表。 –

+0

@AndreasZita,我可以(这是以前的设计的一部分),但我认为这种方式更漂亮,更方便用户。 –

回答

1

使用ToList()您创建一个新的列表,以便后续Addbar_one不添加到bars名单,但到了错误的列表(只是暂时存在)。

由于bar_onebar派生,也可将商品添加到原来的列表bars

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

为了避免误解,你应该改变的bar_ones所以实现,它允许提取列表项类型为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>(); 
    } 
} 

然后,而不是将条目添加到bar_ones,你应该将它们添加到bars。这将自动反映在bar_ones

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