views:

283

answers:

2

I want to do something like this:

List<Child> childList = new List<Child>();
...
List<Parent> parentList = childList;

However, because parentList is a List of Child's ancestor, rather than a direct ancestor, I am unable to do this. Is there workaround (other than adding each element individually)?

+8  A: 

Using LINQ:

List<Parent> parentList = childList.Cast<Parent>().ToList();

Documentation for Cast<>()

recursive
Note that this creates a copy of `childList`, exactly like the not-using-LINQ version by @Andre Pena.
dtb
List<Parent> parentList = childList.OfType<Parent>().ToList(); also works, and is preferable in cases where you are less sure of the content of the starting list.
Cylon Cat
@dtb, you get a new list, but I suspect there's a good chance that the objects in the list are the same objects.
Cylon Cat
If Child inherits from Parent, then you can be 100% certain that the cast will work anyway.
recursive
Besides, C# 4 will bring in more convenient conversion, http://msdn.microsoft.com/en-us/library/ee207183(VS.100).aspx
Lex Li
lextm: not for lists. `List<>`s are neither covariant nor contravariant.
recursive
+7  A: 

Casting directly is not allowed because there's no way to make it typesafe. If you have a list of giraffes, and you cast it to a list of animals, you could then put a tiger into a list of giraffes! The compiler wouldn't stop you, because of course a tiger may go into a list of animals. The only place the compiler can stop you is at the unsafe conversion.

In C# 4 we'll be supporting covariance and contravariance of SAFE interfaces and delegate types that are parameterized with reference types. See here for details:

http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx

Eric Lippert