随意加载你的枪并瞄准,但我想明白为什么你不应该这样做。
我创建了一个自定义类,用于替换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中衍生出来......为什么?
答案 0 :(得分:7)
您应该从Collection<T>
派生,因为它旨在覆盖InsertItem
和RemoveItem
以添加自定义行为,例如您正在做的事情(同时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>
为Add
和Remove
定义了一个非常具体的行为(因为它是一个具体的类),用户可能完全依赖于此行为。
我认为使用new
修饰符通常是正确的,因此应谨慎使用此语言功能,尤其是在公共方法上。
正如其他人所提到的,实施 IList<T>
(使用委托/聚合)可能是更好的选择。