views:

487

answers:

6

I have a few classes: class Vehicle { }

class Car : Vehicle
{
}

I have a list of the derived class: IList<Car> cars;

I would like to convert the list to its base class, and have tried: IList<Vehicle> baseList = cars as IList<Vehicle>;

But I always get null. Also

cars is IList<Vehicle> evaluates to be false.

Granted, I can add the items to a list if I do the following: List<Vehicle> test = new List<Vehicle> ();

foreach ( Car car in cars )
{
   test.Add(car);
}

And I get my list, but I know there has to be a better way. Any thoughts?

+12  A: 

Use IEnumerable<T>.Cast :

IList<Vehicle> vehicles = cars.Cast<Vehicle>().ToList();

Alternatively, you may be able to avoid the conversion to List depending on how you wish to process the source car list.

Lee
Only works in .Net Framework 3.5 (System.Core DLL, System.Linq namespace).
Robert Harvey
@Robert Harvey: The .Net Framework 3.5 has been released almost two years ago. I think it is safe to assume that everyone has it by now unless they have a very good reason not to.
DrJokepu
Note that this results in a new list, not a reference to the same list.
configurator
+7  A: 

That sort of polymorphism that lets you cast IList<Car> to IList<Vehicle> is unsafe, because it would let you insert a Truck in your IList<Car>.

Novelocrat
He's not trying to cast it, but create a new list instance.
recursive
uh, no. He's trying to assign a (reference to a) list of the base type from a (reference to a) list of the derived type, and wondering why he gets null. If he were trying to make a new instance, this would work fine.
Novelocrat
Oh, right. I didn't read close enough.
recursive
+2  A: 

Here are a couple of approaches using Linq:

IList<Derived> list = new List<Derived>();
list.Add(new Derived());

IList<Base> otherlist = new List<Base>(from item in list select item as Base);
IList<Base> otherlist2 = new List<Base>(list.Select(item => item as Base));
recursive
+1  A: 
var vehicles = cars.OfType<IVehicle>()
Abhijeet Patel
+2  A: 

You're facing the problem that there is limited co- and contravariance in C#. There is an interesting approach in C# 4.0, described here at the very ending. However, it creates some other limitations that are related to the truck-problem in the answer from Novelocrat.

Marc Wittke
+2  A: 

You can also take a look on Krzysztof's Cwalina article, Simulated Covariance for .NET Generics

Bolek Tekielski