IList <type>到IList <basetype> </basetype> </type>

时间:2009-09-21 22:40:54

标签: c# .net inheritance

我有几节课:

class Vehicle
{
}

class Car : Vehicle
{
}

我有一个派生类的列表:     IList<Car> cars;

我想将列表转换为其基类,并尝试过:     IList<Vehicle> baseList = cars as IList<Vehicle>;

但我总是得到null。还

cars is IList<Vehicle> evaluates to be false.

当然,如果我执行以下操作,我可以将项目添加到列表中:

List<Vehicle> test = new List<Vehicle> ();

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

我得到了我的清单,但我知道必须有更好的方法。 有什么想法吗?

8 个答案:

答案 0 :(得分:20)

使用IEnumerable<T>.Cast

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

或者,您可以避免转换为List,具体取决于您希望如何处理源汽车列表。

答案 1 :(得分:11)

允许您将IList<Car>投射到IList<Vehicle>的那种多态性是不安全的,因为它会让您在Truck中插入IList<Car>

答案 2 :(得分:4)

你面临的问题是C#中的共同和逆转是有限的。在C#4.0中有一种有趣的方法,描述为here at the very ending。然而,它在Novelocrat的答案中创造了一些与卡车问题相关的其他限制。

答案 3 :(得分:3)

以下是使用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));

答案 4 :(得分:2)

您还可以查看Krzysztof的Cwalina文章,Simulated Covariance for .NET Generics

答案 5 :(得分:1)

var vehicles = cars.OfType<IVehicle>()

答案 6 :(得分:0)

如果你必须一直使用IList,那么你运气不好,上面的答案可以帮到你。但是,如果您可以使用IList作为IEnumerable进行投放,然后只需将IList重新投放到目的地,那就可行,因为IEnumerable可以接受此类作品实践。

// At the source or at the model.
IEnumerable<BaseType> list = new List<Type>();
// At the destination.
IList<BaseType> castedList = (IList<BaseType>)list;

尽管由于编译器无法强制执行这些操作,但您必须手动确保类型和基本类型确实匹配。当然。

答案 7 :(得分:0)

请注意,来自.NET 4.5+的IReadOnlyList<T>将使您可以毫无问题地将IReadOnlyList<Car>投射到IReadOnlyList<Vehicle>中。 List<T>Collection<T>实现此接口。