Prefer inheritance or containment when creating custom collections?

I need special collection classes. Let's call them FooItems and BarItems.

I basically need all the List functions, but I need to do some extra work when new items are added or removed from the collection.

My first stab at this was to just get the list and list and then create my own add and remove methods. This, of course, creates a function to hide the side effect, and the compiler suggests using the "new" keyword to explicitly hide the base classes.

public class FooCollection : List<Foo>
{
    public new void Add(Foo foo)
    {
        // Do my work then...
        base.Add(foo);
    }
}

      

It sounds smelly though. This can cause problems if someone is referencing the FooCollection via a List or IList reference, as it will not call my (not virtual) Add function, but rather the List version.

Of course, in my current code this is unlikely to happen ... but the future cannot be predicted.

Another option, of course, is to reimplement the IList interface and contain a List, but that stinks of DRY violation (and that's also a lot of work, especially for multiple collections).

I'm already leaning towards containment as the preferred method .. just wondering if anyone else has any input on this.

+2


source to share


2 answers


Prefer composition in this case.



You have to realize IList<T>

, but never open List<T>

directly (including through inheritance) in the event of a public API. It should be implementation detail.

+4


source


I agree with the smell and recommend containment. If you want all the functionality in IList<T>

, you're probably out of luck with how simple it is. Can you use, say, ICollection<T>

instead?



EDITED If you need to do this multiple times, you can always create MyList<T> : IList<T>

with virtual implementations. At least you only implement most of the interface once.

+3


source







All Articles