2013-12-10 43 views
6

随意加载你的枪支并瞄准目标,但我想明白你为什么不应该这样做。自定义(派生)列表<T>

我创建了旨在替换表的任何实例(我用它来更新他们身后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中派生出来,为什么?

+11

你听说过ObservableCollection吗? http://msdn.microsoft.com/en-au/library/ms668604(v=vs.110).aspx和http://stackoverflow.com/questions/3167752/is-there-a-way-to-convert -an-observable-collection-to-a-list – Aybe

+0

我正在使用Windows Forms.Net 3.5 – user1830285

+0

使用'new'修饰符从基类中隐藏成员绝不是一个好主意。如果你真的想从'List <>'派生,给你的方法一些新的名字,比如'AddAndRaiseEvent'或者类似的。然而,'List <>'类并不是真正用于这种用途。还有其他一些类提供了更多'虚拟'成员,这些成员在继承它们时会有所帮助。 –

回答

7

您应该Collection<T>派生,因为它的设计,让您可以覆盖InsertItem,并RemoveItem添加自定义的行为,如你在做什么(也SetItem,以改变现有的项目时,添加自定义行为)。

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

对您而言,任何投到IList<T>或基类List<T>的人都将绕过您的自定义添加/删除功能。

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

UPDATE

请告诉我语法揭露的构造吗?

很简单:

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); 
+0

任何投向“IList ”界面的人都会失去新的功能,但是任何投向基本类“List ”的人(如MartinStettner的回答)都会失去。 –

+0

“你可以从你的派生类暴露这个来包装一个由......生成的列表......请说明什么语法来暴露构造函数?我喜欢这个实现 – user1830285

+0

它确定了它:public ListwAddRemove(List incomingList):base(incomingList){} – user1830285

2

其一,

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

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

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

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

我认为这通常适用于使用new修饰符,因此应谨慎使用此语言功能,特别是在公共方法上。

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