上传和通用列表
我有以下类层次结构:
public abstract class BaseData { //some properties } public class CoData : BaseData { //some properties }
我正在使用一个方法,该方法要求返回类型为List
。 在该方法中,我可以访问List
public List Save() { List listCoData = GetData(); return listCoData; }
如果我理解正确,我可以从CoData
到BaseData
。 但是,当我有一个列表时,即使我明确地试图进行类型转换,它也会出错。
错误:
Error 118 Cannot implicitly convert type 'System.Collections.Generic.List' to System.Collections.Generic.List'
编辑:
mquander的转换方法似乎在3.0中适用于我
转发也是以同样的方式完成的吗? 从
ie。我可以这样做 – List listCoData = listBaseData.Cast().ToList();
是; 欢迎来到差异。 最终,它不是 BaseData
的列表 – 例如,如果你有另一个子类, List
会(在编译时)让你。添加它…但运行时类型不会让你。 编译器阻止你犯错误。
在某些情况下,generics可以在这里提供帮助……我在本博文的最后讨论这个问题。 请注意,.NET 4.0差异不适用于列表。
这对于您的集合的参数称为“协方差”,而C#现在不支持这种协方差。 在C#4.0中,用户定义的类型和一些内置类型(如IEnumerable
将支持此function。
在此期间,您可以通过使用显式强制转换成员创建新枚举来解决此问题(您可能需要考虑将此处的返回类型更改为IEnumerable
这样您就不必实际烹饪新的集合每时每刻:)
public List Save() { List listCoData = GetData(); return listCoData.Cast().ToList(); }
根据GetData的工作方式,您可能还会考虑这样的结构:
public List Save () where T : BaseData { return listCoData = GetData (); }
编辑 :实际上,正如Marc和其他人无疑会指出的那样, List
不能像这样协变,因为你可以以破坏类型安全的方式添加成员。 但是,如果您发回IEnumerable
,则可以在此处使用协方差。
编辑2 :回答您的其他问题:
我可以这样做吗?
List
listCoData = listBaseData.Cast ().ToList();
编号listBaseData.Cast
返回List
类型的对象,该对象不能直接转换为List
。 这就是为什么我们必须首先进行这项工作。
mquander解决方案的另一个变体是实现Save as:
public List Save() { List listCoData = GetData(); return listCoData.ConvertAll( delegate(CoData c) { return c as BaseData; }); }
这将允许您在匿名委托中执行一些额外的处理,而不仅仅是强制转换。
这里要记住的重要一点是,当CoDatainheritance自BaseData时,List不会从Listinheritance。
您必须等到C#4.0才能使用通用协方差 。