List属性,返回其他列表属性的子集,但可以更改

时间:2017-06-27 12:55:04

标签: c# list enums

在我的应用程序中,我有一个具有枚举属性的对象列表。为了使该类稍微更友好,我决定添加一个列表,根据它们的枚举属性返回这些对象的特定主题。

我遇到的问题是,如果我向这个子集添加对象,它就不会更新主列表。

这可能吗?

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" });
}

3 个答案:

答案 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_onebarType枚举。在当前的方法中,每个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; }
  }