无法传递派生列表<>

时间:2010-03-11 08:48:09

标签: c# generics inheritance casting

我有

class A
{}

class B : A
{}

我还有一个需要List参数的方法

void AMethod(List<A> parameter)
{}

为什么我不能

List<B> bs = new List<B>();
AMethod(bs);

其次,最优雅的方法是什么?

问候

4 个答案:

答案 0 :(得分:7)

与其他答案相反,.NET 4.0中不支持 。只有接口和代理支持通用差异。但是,.NET 4.0 允许您执行此操作:

void AMethod(IEnumerable<A> parameter) {}
...
List<B> list = new List<B>();
AMethod(list);

在.NET 3.5中,您可以使用Cast

来完成同样的工作
void AMethod(IEnumerable<A> parameter) {}
...
List<B> list = new List<B>();
AMethod(list.Cast<A>());

另一种方法是使AMethod通用:

void AMethod<T>(List<T> parameter) where T : A
...
List<B> list = new List<B>();
AMethod(list); // Implicitly AMethod<B>(list);

可能会或可能不会根据您的需要做什么 - 这取决于您在AMethod中的行为。如果您需要添加A类型的新项目,那么您将遇到问题 - 这是正确的。如果您只需要获取列表 out 的项目,那就没问题了。

答案 1 :(得分:5)

您可以将方法签名设为通用,如下所示:

void AMethod<T>(List<T> parameter) where T : A
{}

或者,您可以等待.NET 4,其中IEnumerable支持此方案&lt;&gt;

答案 2 :(得分:4)

查看Covariance and Contravariance FAQ。有一些很好的解释和例子(对于即将推出的c#4.0)。

答案 3 :(得分:1)

原因是仿制药不支持协方差;我已经读到这将在4.0中出现

这就是为什么你无法传递预期基类型的列表

http://www.boyet.com/Articles/CSharpCovarianceOne.html