簡體   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