繁体   English   中英

列表<Type>到 IList<BaseType>

[英]IList<Type> to IList<BaseType>

我有几节课:

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);
}

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

使用IEnumerable <T> .Cast

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

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

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

您面临的问题是 C# 中的协变和逆变有限。 C# 4.0 中有一个有趣的方法, 在最后的. 但是,它在 Novelocrat 的答案中产生了一些与卡车问题相关的其他限制。

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

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

var vehicles = cars.OfType<IVehicle>()

如果您必须一直使用IList ,那么您就不走运了,上面的答案可以帮助您。 但是,如果您可以使用转换为IEnumerableIList ,然后简单地在目标位置重新转换为IList ,那将起作用,因为IEnumerable可以接受这种做法。

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

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

请注意,.NET 4.5+ 中的IReadOnlyList<T>将允许您将IReadOnlyList<Car>转换为IReadOnlyList<Vehicle>没有问题。 List<T>Collection<T>实现了这个接口。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM