我有几节课:
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);
}
我得到了我的清单,但我知道必须有更好的方法。 有什么想法吗?
答案 0 :(得分:20)
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>
实现此接口。