使用 new 隐藏非虚拟成员的替代方法

Alternative to hiding non-virtual members with new

假设我想做这样的事情:

class Foo
{
    public event BarHandler Bar;
    ...
}

class FooList<T> : List<T> where T : Foo
{
    public override void Add(T item)
    {
        item.Bar += Bar_Handler;
        base.Add(item);
    }

    private void Bar_Handler ...

    ...
}

但是List<T>中的Add不是虚拟的,所以我不能使用override,我不得不求助于new。然而,这不提供多态性,我担心通过将 FooList 简单地引用为 List 可能会引入细微的错误,这将导致我的事件处理程序未被添加。

我目前的具体情况是:我想为实现 INotifyPropertyChanged 的项目子类化 ObservableCollection,如果它们是 add/remove 这些项目的事件处理程序 added/removed。然后我提供一个事件,如果集合中的任何项目发生变化,就会引发该事件。

我想要针对我的特定问题以及潜在的一般问题的解决方案,因为这是我偶然发现的几次,来自 java 背景。

您可以实现 IList<T> 接口并保存一个内部 List<T> 成员变量,而不是扩展 List<T>。这样你就不会破坏现有的 List<T> 功能并且仍然实现与 List<T>.

相同的接口

示例:

class FooList<T> : IList<T> where T : Foo
{
    private List<T> m_internalList = new List<T>();

    public void Add(T item)
    {
        item.Bar += Bar_Handler;
        m_internalList.Add(item);
    }

    // other methods
}

List<T> 不打算继承,因此 Add 方法不是虚拟的,但 Collection<T> 是。您可以改为继承 Collection<T> 并覆盖 InsertItem 方法。

internal class MyCollection<T> : Collection<T> where T : Foo
{
    protected override void InsertItem(int index, T item)
    {
        item.Bar += Bar_Handler;
        base.InsertItem(index, item);
    }
}

相关:Why not inherit from List<T>?

FWIW ObservableCollection<T> class本身继承Collection<T>.