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 pass List<Foo>
into IEnumerable<IFoo>
in .NET 4, since it's defined IEnumerable<out T>
).
The reason List<T>
is not covariant, btw, is because it's not defining a read only contract. Since List<T>
explicitly allows you to add elements (via Add(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 type Bar
(if Bar
derives from IFoo
) to the list, but that would fail, since the list is really a List<Foo>
, not a List<IFoo>
. Since IEnumerable<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.