C# IList到IList

C# IList到IList,c#,.net,inheritance,C#,.net,Inheritance,我有几门课: class Vehicle { } class Car : Vehicle { } 我有一个派生类的列表: 汽车 我想将列表转换为其基类,并已尝试: IList baseList=作为IList的车辆 但我总是得到空值。也 当然,如果我执行以下操作,我可以将项目添加到列表中: List<Vehicle> test = new List<Vehicle> (); foreach ( Car car in cars ) { test.Add(car)

我有几门课:

class Vehicle
{
}

class Car : Vehicle
{
}
我有一个派生类的列表: 汽车

我想将列表转换为其基类,并已尝试: IList baseList=作为IList的车辆

但我总是得到空值。也

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

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

foreach ( Car car in cars )
{
   test.Add(car);
}
我得到了我的名单,但我知道必须有更好的办法。 有什么想法吗?

使用:


或者,根据您希望如何处理源汽车列表,您可能能够避免转换为列表。

这种让您将IList转换为IList的多态性是不安全的,因为它会让您在IList中插入卡车。

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

您面临的问题是C中存在有限的协方差和逆变。C 4.0中有一种有趣的方法,如前所述。然而,它在Novelocrat的回答中产生了一些与卡车问题相关的其他限制。

你也可以看看Krzysztof的Cwalina文章,

如果你必须一直使用IList,那么你就不走运了,上面的答案可以帮助你。但是,如果您可以使用一个强制转换为IEnumerable的IList,然后在目的地简单地重新强制转换为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将允许您将IReadOnlyList强制转换为IReadOnlyList,而不会出现任何问题。列表和集合实现了这个接口。

他没有试图强制转换它,而是创建了一个新的列表实例。呃,没有。他试图从对派生类型列表的引用中为基类型列表分配一个引用,并想知道为什么他会得到null。如果他试图提出一个新的例子,这会很好。至少与之相关。罗伯特·哈维:当然有另一种方法;他可以创建一个基本上是现有IList的包装器的IList实现。这样,他就不必强制转换所有元素,只需转换所需的元素。@Robert Harvey:.Net Framework 3.5已经发布将近两年了。我认为可以安全地假设每个人现在都有,除非他们有很好的理由不这样做。请注意,这会导致一个新的列表,而不是引用同一个列表。
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));
var vehicles = cars.OfType<IVehicle>()
// At the source or at the model.
IEnumerable<BaseType> list = new List<Type>();
// At the destination.
IList<BaseType> castedList = (IList<BaseType>)list;