Why and when to inherit from Collection<T>

I don't understand why (and when) we need to create our own Collection class like this.

You don't really "need" to; you could just use Collection<IFoo> directly, but having a specific class can help readability.

Also, it allows you to add specific behavior for this collection type as the Collection<T> class allows most operations to be redefined by overriding virtual methods; this allows you to customize the behavior of the standard collection methods.

So, for example, while you cannot directly override the Add method, you can override InsertItem which is then used by Add, AddRange etc.

Why not just use the build-in collection (array, List, Dictionary, ...)

An array has a fixed length, so you can't add or remove items; so it's not really equivalent. Dictionary<K,V> associates a value with a key, so it has a clearly different purpose. List<T> could be used instead, as long as you don't need to customize the behavior; this class is not designed for inheritance, since its methods are non-virtual.

What's the data structure used in Collection ?? array? or linked list?

Collection<T> acts as a wrapper around another IList<T>. By default, it uses a List<T> (which is based on an array), but you can pass any other IList<T> implementation to the constructor, and it will use that instead.


By stating that you are inheriting the Collection<T> class, you declare that your class IS-A Collection<T>, meaning that you have all it's API implemented (either by the derived class or by base the Collection<T> class).

The advantage in the inheritance is that you can decide to override some of the methods and handle them in a way you find more suitable to your needs or to the type T (IFoo in your case).

In the same manner you can also decide to extend your API in order to support some other functionality that you find appropriate for your situation.

For example if you class IFoo looks some thing like this:

public interface IFoo
{
   int a;
   int b;
}

In your derived class you can add an overload to the Remove that will look something like:

public bool Remove(int a, int b )...

And it will remove all occurrences of items that has certain values for a and b