I have a class Foo implementing the IFoo interface. I have a method taking a List<IFoo> as a parameter. However, it cannot convert from List<Foo> to List<IFoo> – this surprises me, since Foo implements the IFoo interface.
How can I get around this, and why does this occur? (Always good to learn from mistakes)
This is because
List<T>is not covariant. For details, see Covariance and Contravariance in C#.If you can make your method work on
IEnumerable<T>instead, this will work (you can passList<Foo>intoIEnumerable<IFoo>in .NET 4, since it’s definedIEnumerable<out T>).The reason
List<T>is not covariant, btw, is because it’s not defining a read only contract. SinceList<T>explicitly allows you to add elements (viaAdd(T)), it’s not safe to allow covariance to work. If this was allowed, the method would expect to be able to add an element of typeBar(ifBarderives fromIFoo) to the list, but that would fail, since the list is really aList<Foo>, not aList<IFoo>. SinceIEnumerable<T>only allows you to iterate through the list, but not modify it, it can be covariant and just work as expected in this case.