views:

352

answers:

3

I want to make a List and add derived classes to this list.

I see here that this is not possible by design in .NET: http://msdn.microsoft.com/en-us/library/aa479859.aspx#fundamentals_topic12

So what is the best practice solution to this? I guess I can box my derived classes to make them look like my superclass but that feels a little unwieldly. I suppose I should have designed my classes differently....but how?

+3  A: 

If I understand what you are trying to do, you should be able to do it just fine.

List<SuperClass> myList = new List<SuperClass>();

SubClass item1 = new SubClass();
SuperClass item2 = new SuperClass();

myList.add(item1);
myList.add(item2);

This is valid code, and then you can easily retrieve the elements from the list, and use the basic rules of polymorphism for changing the types of the objects accordingly.

Brian
+1  A: 

That would work fine. While you won't know the exact type of an item in the list (without casting) there are no problems with adding a derived type to a collection of base types.

What the article links to is the case where you try to use a collection of derived types as a collection of base types:

void DisplayFruit(List<Fruit> fruit)
{
    fruit.ForEach(f => Console.WriteLine(f.ToString()));
}

List<Apples> apples = new List<Apples>();
// add apples here

DisplayFruit(apples); //Error!

If apples were declared as a List<Fruit> instead, it would work.

Andy
A: 

As Brian notes, this should work fine. The only common limitation people see in this area is covariance of lists as method arguments - i.e. they find that they can't pass a List<Dog> to a method that accepts a List<Animal>. The answer in that case is generics:

public void Foo<T>(IList<T> list) where T : Animal {...}
....
List<Dog> dogs = ...
Foo(dogs); // implicit <Dog>

For more discussion on covariance (including the C# 4.0 changes that doesn't change the above scenario, see here).

Marc Gravell