The direct cast var ListOfY = (List<Y>)ListOfX
is not possible because it would require co/contravariance of the List<T>
type, and that just can't be guaranteed in every case. Please read on to see the solutions to this casting problem.
While it seems normal to be able to write code like this:
List<Animal> animals = (List<Animal>) mammalList;
because we can guarantee that every mammal will be an animal, this is obviously a mistake:
List<Mammal> mammals = (List<Mammal>) animalList;
since not every animal is a mammal.
However, using C# 3 and above, you can use
IEnumerable<Animal> animals = mammalList.Cast<Animal>();
that eases the casting a little. This is syntactically equivalent to your one-by-one adding code, as it uses an explicit cast to cast each Mammal
in the list to an Animal
, and will fail if the cast is not successfull.
If you like more control over the casting / conversion process, you could use the ConvertAll
method of the List<T>
class, which can use a supplied expression to convert the items. It has the added benifit that it returns a List
, instead of IEnumerable
, so no .ToList()
is necessary.
List<object> o = new List<object>();
o.Add("one");
o.Add("two");
o.Add(3);
IEnumerable<string> s1 = o.Cast<string>(); //fails on the 3rd item
List<string> s2 = o.ConvertAll(x => x.ToString()); //succeeds