Search code examples
c#arrayscovarianceilist

Covariant behaviour of arrays when assigning to IList<T>


I am wondering how an array has different behaviour to List<T>, both which implement IList, where the array appears to be getting around IList's non-covariant nature (it is not defined as IList<out T>), when assigning to IList<IPerson>. In the below example all assignments are ok except for 'people3'. Why does the assignment work in the case of 'people4' for personArray?

public interface IPerson { }
public class Person : IPerson { }

var personList = new List<Person>();
var personArray = new Person[0];

IList<Person> people1 = personList;
IList<Person> people2 = personArray;
IList<IPerson> people3 = personList;
IList<IPerson> people4 = personArray;

Solution

  • It's because that kind of covariance is a bad thing and C# only supports it with arrays because Java supports it.

    This gives a runtime error

            object[] myArray = new string[1];
            myArray[0] = 1;
    

    This gives a compile time error

            List<object> myList = new List<string>(1);
            myList[0] = 1;