52

What is the fastest way to implement a new class that inherits from List<T>?

class Animal {}

class Animals : List<Animal> {} // (1)

One problem I've encountered: By simply doing (1), I've found that I'm not getting the benefit of inheriting any constructors from List<T>.

In the end, I'd like Animals to behave a lot like a List<T> (e.g., can be constructed, compatibility with Linq). But in addition, I'd also like to be able to add my own custom methods.

3
  • 1
    What you've posted looks pretty good to me!
    – Stuart
    Commented Mar 21, 2011 at 10:16
  • Your code above would do it. You would need to implement any constructors and just call through to the relevant constructor on the base call (List<Animal>). You can create any custom methods within the Animals class
    – detaylor
    Commented Mar 21, 2011 at 10:16
  • 1
    possible duplicate of C#: Inheritance Problem with List<T> Commented Mar 21, 2011 at 12:29

7 Answers 7

53

If you want to create a publicly exposed animal collection you should not inherit from List<T> and instead inherit from Collection<T> and use the postfix Collection in the class name. Example: AnimalCollection : Collection<Animal>.

This is supported by the framework design guidelines, more specifically:

DO NOT use ArrayList, List<T>, Hashtable, or Dictionary<K,V> in public APIs. Use Collection<T>, ReadOnlyCollection<T>, KeyedCollection<K,T>, or CollectionBase subtypes instead. Note that the generic collections are only supported in the Framework version 2.0 and above.

13
  • 92
    I fail to understand why I should follow this guideline. Commented Mar 21, 2011 at 10:32
  • 1
    +1 this would really make sense if the OP wants to do something within the list itself.The OP could override basic methods. I don't really see any other value in inherit from a List<T> just to call your list type Animal right?
    – gideon
    Commented Mar 21, 2011 at 10:35
  • 8
    @Martinho Fernandes, it's a guideline like any other, but if you provide a typed collection in your public API you can change it in future versions since it's your type. If you directly use List<T>, then you're out of luck. Commented Mar 21, 2011 at 10:37
  • 8
    also consider using interfaces i.e. ICollection<T>, IEnumerable<T>, IDictionary<TKey,TValue> etc.
    – chillitom
    Commented Mar 21, 2011 at 10:40
  • 8
    @Martinho: maybe 'cause you can't override Add/Remove methods while with Collection<T> you can. BTW, I'd prefer to implement IList<T>or ICollection<T> using an inner List<T> instead of inherit from Collection<T>...
    – digEmAll
    Commented Mar 21, 2011 at 10:40
32

Constructors are not inherited along with the class. You have to reimplement your desired constructors.

public class AnimalsCollection : List<Animal>
{
     public AnimalsCollection(IEnumerable<Animal> animals) : base(animals) {} 
}
8
  • 15
    Downvoters want to say why? He asked why he "didn't have any constructors", which is why my answer is the way it is. If you disagree, how about leaving some feedback? Commented Mar 21, 2011 at 11:05
  • 6
    Same reason as for Tokk. But this shows once again why anonymous downvotes suck: It’s just not helping. Commented Mar 21, 2011 at 11:56
  • 1
    see: stackoverflow.com/questions/3748931/ stackoverflow.com/questions/898152/ stackoverflow.com/questions/794679/ stackoverflow.com/questions/5207459/ stackoverflow.com/questions/2136213/ stackoverflow.com/questions/349904 stackoverflow.com/questions/1257214 Commented Mar 21, 2011 at 12:28
  • 3
    @George Stocker: That still wasn't the OP's question. It's good to give him a nudge in a better direction, but I sort of hate that we have to analyze every person's approach before answering the actual question the person had. Knowing that constructors are not inherited is a useful thing on its own. Commented Mar 21, 2011 at 12:34
  • 3
    @Anderson Yes but the general sentiment here isn’t to give the OPs a fish but to teach them fishing. That said, I wouldn’t have downvoted this answer and I I can only say again that anonymous downvotes suck. Commented Mar 21, 2011 at 12:40
14

Deriving from List<T> is not advised. Primarily because List was never meant for extension, but for performance.

If you want to create your own specific collection, you should inherit from Collection<T>. In your case it would be:

class Animals : Collection<Animal> {}
2
  • 2
    I did according to ur advice and inherits from Collection<MyClass>. But having problem somewhere like Collection<T> does not support methods like Sort, Find, FindAll and many more very useful methods. I have to change it to inherit from List<MyClass>. Is there any thing that I can do..?
    – shashwat
    Commented Feb 1, 2013 at 14:58
  • 4
    @shashwat It doesn't have those methods because a Collection is supposed to be a general class for representing any group of items. For instance, a mathematical set has no specific order, and cannot be sorted. Find may be ambiguous if elements are not unique. Both of these cases should be part of what Collection can be used for, so it cannot include Sort and Find without losing generality. Although there should probably be a ListCollection : Collection, since it seems that that's what people use it for most commonly.
    – Superbest
    Commented Feb 11, 2014 at 2:00
6

Bear in mind that inheriting from List isn't as fully featured as you may need, a lot of the members are not virtual so the only way of covering the base implementation is to shadow it with the new syntax (as opposed to override).

If you need to start exposing custom behaviour on standard list actions, I would implement all the list interfaces on a type that simply uses an inner list for the actual storage.

This is heavily dependent on your final requirements.

2
  • I did according to ur advice and inherits from Collection<MyClass>. But having problem somewhere like Collection<T> does not support methods like Sort, Find, FindAll and many more very useful methods. I have to change it to inherit from List<MyClass>. Is there any thing that I can do..?
    – shashwat
    Commented Feb 1, 2013 at 15:01
  • 3
    @shashwat Sort, Find and FindAll etc can be implemented in terms of LINQ for IEnumerable<T>, so this is not a problem. Commented Feb 12, 2014 at 5:38
4

It isn't necessary to inherit from List to use collection initialization syntax or use Linq extension methods.

Just implement IEnumerable and also an Add method.

3
class Animals : List<Animal> {}

seemes the best way, because you can use it just after defining it like this.

So my advice is your questions title: Inherit List<T> ;-)

3
-1

Keeping in mind that if you want all the functionality of List<T>, which is:

public class List<T> : ICollection<T>, IEnumerable<T>, IEnumerable, IList<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection, IList

Then your class can inherit those.

However, if your class is not part of an API that could be serialized, List<T> is suitable.

public class MyItems : List<MyItem>
{
    public MyItems() : base()
    {
    }
}

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.