.NET Casting通用列表

有人可以向我解释为什么在.NET 2.0中我有一个接口, IPackable和一个实现该接口OrderItem的类,当我有一个接收List ,传入ListList不行?

有谁知道我怎么能完成这个function?

码:

 public interface IPackable { double Weight{ get; } } public class OrderItem : IPackable public List GetForShipWeight(List packages) { double totalWeight = 0; foreach (IPackable package in packages) { totalWeight += package.Weight; } } 

以下代码不起作用。

 List orderItems = new List(); List shipMethods = GetForShipWeight(orderItems); 

该function称为协方差/逆变,将在c#4.0中得到支持。 你可以在这里阅读: http : //blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx

JMD是正确的一半。 事实上,说我们能够使用C#4.0转换通用列表是完全错误的。 确实,C#4.0将支持协方差和逆变,但它只适用于接口和委托,并且会有很多约束。 因此,它不适用于List

原因很简单。

如果B是A的子类,我们不能说ListList的子类。

这就是原因。

List公开了一些协方差方法(返回值)和一些逆变方法(接受一个值作为参数)。

例如

  • List公开Add(A);
  • List公开Add(B);

如果Listinheritance自List …,那么你可以进行List.Add(A);

因此,您将失去仿制药的所有类型安全性。

JMD的答案是正确的。 要解决此问题,您可以尝试以下方法:

 List orderItems = new List(); List shipMethods = GetForShipWeight(orderItems); 

或者,如果列表必须强类型为OrderItems,那么这个(仅限3.0,抱歉):

 List shipMethods = GetForShipWeight(orderItems.Cast().ToList()); 

另一种适用于.NET 3.5的解决方案

 List shipMethods = GetForShipWeight(orderItems).ConvertAll(sm => sm as IShipMethod); 

实际上,你可以通过使GetForShipWeight成为通用函数来解决这个问题:

 public interface IPackable { double Weight { get; } } public interface IShipMethod { } public class OrderItem : IPackable { } public List GetForShipWeight(List packages) where T : IPackable { List ship = new List(); foreach (IPackable package in packages) { // Do something with packages to determine list of shipping methods } return ship; } public void Test() { List orderItems = new List(); // Now compiles... List shipMethods = GetForShipWeight(orderItems); }