在我的应用程序中,我有一个具有枚举属性的对象列表。为了使该类稍微更友好,我决定添加一个列表,根据它们的枚举属性返回这些对象的特定主题。
我遇到的问题是,如果我向这个子集添加对象,它就不会更新主列表。
这可能吗?
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 :(得分:1)
通过使用ToList()
,您可以创建一个新列表,以便后续的Add
不会将新的bar_one
添加到bars
列表中,而是添加到错误的列表中(只是暂时存在)。
由于bar_one
来自bar
,您还可以将该项添加到原始列表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_one
和barType
枚举。在当前的方法中,每个barType
都有一个枚举和一个类。因此,对于新类型,您需要创建两者。
最好选择一种方式,例如只有没有枚举的类层次结构(从OOD的角度来看这更好)。
答案 1 :(得分: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
。
答案 2 :(得分: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; }
}