无法将通用列表转换为自定义列表类型

时间:2013-05-10 17:55:09

标签: c# .net generics collections casting

我有两个班级:

public class MyClass
{
    public int Foo { get; set; }
    public string Bar { get; set; }
}

public class MyList : List<MyClass>
{
}

在其他代码中,我正在为数据库中的每条记录创建MyClass的实例,我想在MyList实例中将它们全部返回:

var records = _repository.GetRecords();
return (MyList) records.Select(x => x.ConvertTo<MyClass>()).ToList();

代码编译得很好,但它正在抛出运行时 InvalidCastException

  

无法将类型为'System.Collections.Generic.List`1 [MyClass]'的对象强制转换为'MyList'。

我不明白为什么会发生此错误,因为MyList List<MyClass>

我发现了一些与协方差有关的相关问题。 This question与我的问题最相似,但我不知道如何调整答案来解决我的问题。

我的问题:
如何从数据库记录中构建MyList实例?

我正在使用C#和.NET 4.0

2 个答案:

答案 0 :(得分:8)

每个MyList都是List<MyClass>,但不是每个List<MyClass>都是MyList。例如,如果您在MyList上有自定义属性,则Linq的ToList方法将不知道它。

您可以使用MyList复制构造函数创建新的List<T>

return new MyList(records.Select(x => x.ConvertTo<MyClass>()).ToList());

修改

正如@ekolis庄严地注意到的那样,你需要明确地&#34;继承&#34; List<T>复制构造函数:

public class MyList : List<MyClass>
{
    public MyList(IEnumerable<MyClass> list)
        : base(list)
    {
    }
}

我还会退一步看看你是否真的需要一个MyList课程,或者你是否只能使用List<MyClass>(或者只是IEnumerable<MyClass>

答案 1 :(得分:0)

您可以将派生类强制转换为基类,但不能以其他方式执行。 如果你有这个:

public class Base {}
public class Derived : Base {}

您可以将Derived投射到Base,但无法将Base投射到Derived

Base b = (Base)new Derived();

会奏效 但不是

Derived d = (Derived)new Base();

Derived类可能比Base类有更多信息,这就是为什么

在你的情况下,@D Stanley为你提供了解决方案