如何将List <Child>传递给参数List <Parent>的方法?

MrG*_*les 4 .net c# generics inheritance c#-4.0

我已经离开遗产一段时间了,需要一点帮助.

我有一个抽象的基类Chief.有两种继承类ShipVehicle,共享通过几个属性Chief.

我有一个使用这些常见属性的方法:

public static void AssignRandomProperties(PSetList routeSettings, List<Chief> theChiefs)
Run Code Online (Sandbox Code Playgroud)

但是当我试图传递一个

List<Ship> 
Run Code Online (Sandbox Code Playgroud)

或者a

List<Vehicle> 
Run Code Online (Sandbox Code Playgroud)

我被告知他们无法转换.这是一个示例方法调用:

ChiefRouteRandomizer.AssignRandomProperties(s.Route, theVehicles);
Run Code Online (Sandbox Code Playgroud)

我当然假设List<Vehicle>将被视为一个List<Chief>时间作为参数传递AssignRandomProperties,但显然不是.列表是否需要转换为List<Chief>第一个?如果是这样,怎么样?

cdh*_*wie 8

首先解释一下.您无法转换List<Vehicle>为,List<Chief>因为Add方法将具有签名void List<Chief>.Add(Chief item),您将能够将该Chief类的实例存储在声明为仅包含Vehicles 的列表中.这会破坏类型系统; 因此不允许这样做.

解决这个问题的最简单方法是传入theVehicles.ToList<Chief>().但是,这将创建一个新列表.这有两个含义:(1)你会通过复制列表来浪费内存,(2)如果方法要改变列表本身(添加/删除项目或用其他成员替换成员),你将看不到这些更改在theVehicles名单上.(如果列表中的引用指向的对象是唯一被修改的对象,则这不是问题.)

如果您可以控制AssignRandomProperties方法,请考虑使用此签名:

public static void AssignRandomProperties<T>(
    PSetList routeSettings,
    IList<T> theChiefs) where T : Chief
{
    ...
}
Run Code Online (Sandbox Code Playgroud)