Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to hiding non-virtual members with new

Tags:

c#

inheritance

Suppose I want to do something like this:

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 ...

    ...
}

But Add in List<T> is not virtual, so I cannot use override, I would have to resort to new instead. This however does not provide polymorphism, and I am worried about subtle bugs that could be introduced by refering to FooList as simply List, which would lead to my Event-Handler not being added.

My current specific case of this is: I want to subclass ObservableCollection for Items that implement INotifyPropertyChanged, and add/remove an Event-Handler to those Items if they are added/removed. Then I provide an Event that is raised if any Item in Collection changes.

I would like a solution for my particular problem as well as the underlying general problem, as this is somethink I stumbled upon a few times, coming from a java background.

like image 973
quantumbyte Avatar asked Jan 01 '26 21:01

quantumbyte


2 Answers

Instead of extending List<T> you could implement the IList<T> interface and hold an internal List<T> member variable. That way you don't break the existing List<T> functionality and still implement the same interface as List<T>.

Example:

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
}
like image 184
Thorsten Dittmar Avatar answered Jan 03 '26 10:01

Thorsten Dittmar


List<T> is not intended to inherit and thus Add method isn't virtual, but Collection<T> is. You can inherit Collection<T> instead and override InsertItem method.

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

Related: Why not inherit from List<T>?

FWIW ObservableCollection<T> class itself inherits Collection<T>.

like image 23
Sriram Sakthivel Avatar answered Jan 03 '26 10:01

Sriram Sakthivel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!