为什么采用IEnumerable <interface>的函数不接受IEnumerable <class>?

Mat*_*eld 5 generics ienumerable inheritance covariance c#-3.0

比方说,我有一个班级:

public class MyFoo : IMyBar
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后,我想使用以下代码:

List<MyFoo> classList = new List<MyFoo>();
classList.Add(new MyFoo(1));
classList.Add(new MyFoo(2));
classList.Add(new MyFoo(3));

List<IMyBar> interfaceList = new List<IMyBar>(classList);
Run Code Online (Sandbox Code Playgroud)

但这会产生错误:

`Argument '1': cannot convert from 'IEnumerable<MyFoo>' to 'IEnumerable<IMyBar>' 
Run Code Online (Sandbox Code Playgroud)

为什么是这样?由于MyFoo实现了IMyBar,人们可以预期IEnumerable的MyFoo可以被视为IMyBar的IEnumerable.一个平凡的现实世界的例子是生产汽车列表,然后被告知它不是车辆列表.

这只是一个小小的烦恼,但如果有人能够对此有所了解,我会非常感激.

Meh*_*ari 14

这将在C#4.0中运行!你所说的是通用协方差.

在此期间,您可以使用Cast扩展方法:

List<IMyBar> interfaceList = new List<IMyBar>(classList.Cast<IMyBar>());
Run Code Online (Sandbox Code Playgroud)

  • 为了澄清:CLR v2.0中添加了对变体类型定义的支持.在C#4中添加了对在C#中定义和使用此类内容的支持.在CLR 4中完成了对使用此功能的BCL类型的注释.对于那些认为很容易的人,我希望您能阅读数百页的错误报告该功能到目前为止已生成.改变这种激进的类型系统*不容易*; 一个学者可以证明代数很好地运作与如何使它与现有的数百万行代码一起工作的问题完全无关. (5认同)