Why can't List <parent> = List <child>?

Why won't the following code work?

class parent {} class kid:parent {} List<parent> parents=new List<kid>; 

It seems obvious to me. What's going on here?

+1
source share
5 answers

C # does not currently support covariance .

This is coming in .NET 4.0, however, on interfaces and delegates.

Eric Lippert had a very enjoyable series on this subject on his blog some time ago. Visual Studio magazine also covers it in a recent article .

+10
source

In addition to the lack of general dispersion support in C # prior to version 4.0, the List is modified and therefore cannot be covariant. Consider this:

 void AddOne<T>(List<T> arg) where T : new() { arg.Add(new T()); } void Whoops() { List<parent> contradiction = new List<kid>(); AddOne(contradiction); // what should this do? } 

This will try to add the parent to the list referenced via List, which is unsafe. Arrays are allowed covariant in execution time, but are checked by type during mutation, and an exception is thrown if a new element is not assigned to the type of the element of time of the array.

+4
source

The function you are looking for is called covariance. It is not supported in C # until version 4.0, and then only on interfaces and delegates.

Some related links

+2
source

If you know that List<Parent> contains List<child> , you can use the extension method to "convert" (really just take parent elements that are of type child type and return them to the list, for example, something like:

  public static List<T> Convert<T, T2>(this List<T2> input) { return input.OfType<T>().ToList(); } 

I'm not sure this will help you, but my 2 cents are worth it! I use it quite a lot.

+1
source

As already mentioned, in C # this is not supported. In Java, arrays are covariant, and this can cause some problems. Consider your example, the actual list should be a "kid" list, that is, all objects in it should be "kid" s (or "grandchildren"). But if the link that you use to access the list is a "parent" list, then you can insert a "parent" into the list, which obviously shouldn't happen.

0
source

All Articles