自定义(派生)列表<t> </t>

时间:2013-12-10 11:45:57

标签: c# linq collections derived-class

随意加载你的枪并瞄准,但我想明白为什么你不应该这样做。

我创建了一个自定义类,用于替换List的任何实例(我用它来更新它们后面的XML对象):

public class ListwAddRemove<T> : List<T> {
    public event EventHandler<ListModifyEventArgs> OnAdd;
    public event EventHandler<ListModifyEventArgs> OnRemove;

    new public void Add(T o) {
        base.Add(o);

        if (OnAdd != null) {
            OnAdd(this, new ListModifyEventArgs(o));
        }
    }

    new public void Remove(T o) {
        base.Remove(o);

        if (OnRemove != null) {
            OnRemove(this, new ListModifyEventArgs(o));
        }
    }
}

这个想法是每当我从这个列表中添加或删除一个项目时,我的绑定事件就会触发,我可以自动处理XML。

这就像一个魅力,到目前为止一直很好。

但是如何处理object.ToList()和我的派生版本之间的转换?

很多人都说你应该从Collection中衍生出来......为什么?

2 个答案:

答案 0 :(得分:7)

您应该从Collection<T>派生,因为它旨在覆盖InsertItemRemoveItem以添加自定义行为,例如您正在做的事情(同时SetItem ,在更改现有项目时添加自定义行为。)

因此可以用作IList<T>,任何插入/删除都会自动使用自定义。

在您的情况下,任何投射到IList<T>或基类List<T>的人都会绕过您的自定义添加/删除功能。

Collection<T>还提供了一个构造函数来包装现有列表。您可以从派生类中公开它,以包装由Enumerable<T>.ToList()生成的列表。

<强>更新

  

请问公开构造函数的语法是什么?

很简单:

public class ListwAddRemove<T> : Collection<T>
{
    public ListwAddRemove<T>()
    {
    }

    public ListwAddRemove<T>(IList<T> list) : base(list)
    {
    }

    ... implementation of overrides for InsertItem, SetItem, RemoveItem ...
}

然后按如下方式使用:

IList<SomeType> list = ....ToList();
ListwAddRemove<SomeType> myList = new ListwAddRemove<SomeType>(list);

答案 1 :(得分:2)

一个人,

void DoSomeAddingToList(List<int> list) {
  list.Add(1);
}

var list = new ListwAddRemove<int>();
DoSomeAddingToList(list);

不会触发事件。这可能会产生奇怪的效果,特别是如果你不是唯一一个使用该类的人。

List<T>AddRemove定义了一个非常具体的行为(因为它是一个具体的类),用户可能完全依赖于此行为。

我认为使用new修饰符通常是正确的,因此应谨慎使用此语言功能,尤其是在公共方法上。

正如其他人所提到的,实施 IList<T>(使用委托/聚合)可能是更好的选择。