.NET Casting通用列表
有人可以向我解释为什么在.NET 2.0中我有一个接口, IPackable
和一个实现该接口OrderItem
的类,当我有一个接收List
,传入List
的List
不行?
有谁知道我怎么能完成这个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
。
原因很简单。
这就是原因。
List
公开了一些协方差方法(返回值)和一些逆变方法(接受一个值作为参数)。
例如
如果List
inheritance自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); }