Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List assignment from child to parent

I am trying to do this:

List<Parent> test = new List<Child>();

The complete code of my class is this:

class Program
{
    public static void Main(string[] args)
    {
        List<Parent> test = new List<Child>();

        test.Add(new Child());

        test.Add(new AnotherChild());
    }
}

class Parent { }

class Child : Parent { }

class AnotherChild : Parent { }

Can someebody please explian me why this gives me this error:

Error 2 Cannot convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List' d:\personal\documents\visual studio 2010\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs 20 24 ConsoleApplication3

And why does this work?

Parent[] test = new Child[10];
List<Parent> result = test.ToList();

Thanks :)

-- Right:

Now I know why: List is compiled to List`1 and List to List`2. And they have no relationship.

like image 895
Snake Avatar asked Dec 13 '22 23:12

Snake


2 Answers

Update: because the two types, List<Parent> and List<Child> is not co-variant.

Even though the generic parameter you pass in, Child, inherits Parent, the relationship is not carried into the closed List types. Thus, the resulting two List types are not interchangeable.

.Net 4.0 introduces co-variance/contra-variance. Your code will still not work with .Net 4.0 though, since neither the List class or the IList interface will be changed to be co-variant.

like image 148
Peter Lillevold Avatar answered Dec 15 '22 12:12

Peter Lillevold


You can't do this because List<Child> isn't assignable to List<Parent>, even though Child is assignable to Parent. The List<T> type is invariant.

Is there any reason why you can't use something like this instead?

public static void Main(string[] args)
{
    List<Parent> test = new List<Parent>();

    test.Add(new Child());

    test.Add(new AnotherChild());
}
like image 23
LukeH Avatar answered Dec 15 '22 14:12

LukeH