5

我有两个课程:

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>.

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

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

我正在使用 C# 和 .NET 4.0

4

2 回答 2

9

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

您可以使用复制构造函数创建一个新的:MyListList<T>

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

编辑

正如@ekolis estutely 注意到的那样,您需要显式“继承”List<T>复制构造函数:

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

我也会退后一步,看看你是否真的需要MyList门课,或者你是否可以使用List<MyClass>(甚至只是IEnumerable<MyClass>)。

于 2013-05-10T17:57:52.387 回答
0

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

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

你可以投射DerivedBase,但你不能投射BaseDerived

Base b = (Base)new Derived();

会工作,但不会

Derived d = (Derived)new Base();

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

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

于 2013-05-10T18:01:27.810 回答