views:

44

answers:

2

I have a need for specialized collection classes. Let's call them FooItems and BarItems.

I basically need all the functionality of a List, 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 simply derive from List and List, then create my own Add and Remove methods. This of course creates a function hiding side-effect, and the compiler suggests using the "new" keyword to explictly hid the base classes.

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

This feels smelly though. This can cause problems if someone references the FooCollection via a List or IList reference, since it won't call my (non-virtual) Add function, but rather the List version.

Of course in my current code, that's not likely to happen... but one can never predict the future.

The other option, of course, is to re-implement the IList Interface and contain the List, but that stinks of DRY violation (and It's also a lot of work, especially for multiple collections).

I am already leaning towards containment as the preferred method.. just wondering if anyone else has some input on this.

+4  A: 

Prefer composition in this case.

You should implement IList<T>, but never expose List<T> directly (including via inheritance) in any public API. It should be an implementation detail.

Reed Copsey
+3  A: 

I agree about the smell, and recommend containment. If you need all of the functionality in IList<T>, you're probably out of luck as far as keeping it simple is concerned. Can you use, say, ICollection<T> instead?

EDITED If you need to do this several times over, you can always create MyList<T> : IList<T> with virtual implementations. At least then you're implementing the majority of the interface just once.

Ben M