Casting list of objects to List vs IList

c#, casting

Solution

The compiler knows that a `List<X>` cannot be a `List<Y>`. It therefore gives a compiler error.

However, the second cast could succeed if the `List<X>` is actually some derived class that also implements `IList<Y>`.

You will only get a compile-time error from a cast if neither type is an interface, or if one type is an unrelated interface and the other type is sealed (or a struct).

To quote the spec (§6.4.2)

The explicit reference conversions are:

- From object and dynamic to any other reference-type.

- From any class-type S to any class-type T, provided S is a base class of T.

- From any class-type S to any interface-type T, provided S is not sealed and provided S does not implement T.

- From any interface-type S to any class-type T, provided T is not sealed or provided T implements S.

- From any interface-type S to any interface-type T, provided S is not derived from T.

- [snip]

(emphasis added)

The `provided...` clauses exclude conversions that are actually implicit.

Problem

Just came across this: ``` Func<List<object>> foo = () => new List<object>(); List<string> s = (List<string>)foo(); IList<string> s1 = (IList<string>)foo(); ``` Compiler complains about casting to List (makes sense), but says nothing about IList. Makes me wonder why is that?

Original source

Related problems