上传和通用列表

Dot*_*ude 4 .net c#

我有以下类层次结构:

public abstract class BaseData
{
  //some properties
}

public class CoData : BaseData
{
  //some properties
}
Run Code Online (Sandbox Code Playgroud)

我正在使用一个需要返回类型的方法List<BaseData>.在方法中,我可以访问List<CoData>

public List<BaseData> Save()
{
  List<CoData> listCoData = GetData();
  return listCoData;
}
Run Code Online (Sandbox Code Playgroud)

如果我理解正确,我可以从a CoData到a BaseData.但是,当我有一个列表时,即使我明确地试图进行类型转换,它也会出错.

错误:

Error   118 Cannot implicitly convert type 'System.Collections.Generic.List<CoData>' to System.Collections.Generic.List<BaseData>'
Run Code Online (Sandbox Code Playgroud)

编辑:

mquander的转换方法在3.0中似乎对我有用

转发也是以同样的方式完成的吗?从

即,我可以这样做 - List<CoData> listCoData = listBaseData.Cast<BaseData>().ToList();

Mar*_*ell 10

是; 欢迎来到差异.最终,它不是一个列表BaseData- 例如,如果你有另一个子类,一个List<BaseData>将(在编译时)让你.Add...但运行时类型不会让你.编译器阻止你犯错误.

在某些情况下,泛型可以在这里提供帮助......我在本博客文章末尾对此进行了讨论.请注意,.NET 4.0方差不适用于列表.


mqp*_*mqp 8

这对于您的集合的参数称为"协方差",而C#现在不支持这种协方差.在C#4.0中,用户定义的类型和一些内置类型IEnumerable<T>将支持这一点.

在此期间,您可以通过创建具有显式演员的新枚举来解决它(您可能想要考虑更改您的东西的返回类型,IEnumerable<T>以便您不必一直实际创建新的集合: )

public List<BaseData> Save()
{
    List<CoData> listCoData = GetData();
    return listCoData.Cast<BaseData>().ToList();
}
Run Code Online (Sandbox Code Playgroud)

根据GetData的工作原理,您可能还会考虑这样的结构:

public List<T> Save<T>() where T : BaseData
{
    return listCoData = GetData<T>();
}
Run Code Online (Sandbox Code Playgroud)

编辑:实际上,正如Marc和其他人无疑会指出的那样,List<T>不能像这样协变,因为你可以添加成员,如果它会打破类型安全.但是,如果你发回了IEnumerable<T>s,你可以在这里使用协方差.

编辑2:回答您的其他问题:

我可以这样做吗? List<CoData> listCoData = listBaseData.Cast<BaseData>().ToList();

No. listBaseData.Cast<BaseData>().ToList();返回一个List<BaseData>不能直接转换为a 的类型的对象List<CoData>.这就是为什么我们必须首先去做这个努力.