我有圆的物体(如圈实现IShape接口的数组和我有了的List<IShape>
参数的函数。为什么我不能在我的圈子到此的数组传递?为什么.Net 4不允许我传入一个接口数组?
视觉工作室给我生成错误的说法不能转换List<Circle>
到List<IShape>
我有圆的物体(如圈实现IShape接口的数组和我有了的List<IShape>
参数的函数。为什么我不能在我的圈子到此的数组传递?为什么.Net 4不允许我传入一个接口数组?
视觉工作室给我生成错误的说法不能转换List<Circle>
到List<IShape>
简短的回答是,因为功能Foo
可以实现这样的:
void Foo(IList<IShape> c)
{
c.Add(new Square());
}
如果你通过了List<Circle>
到Foo
,所提供的类型将不能存储Square
,即使类型签名声称它没问题。 IList<T>
不是covariant:一般IList<Circle>
不能是IList<IShape>
,因为它不支持添加任意形状。
修复方法是使用IEnumerable<IShape>
来接受Foo
中的参数,但这在所有情况下都不起作用。 IEnumerable<T>
是协变:专门的IEnumerable<Circle>
符合一般IEnumerable<IShape>
的合同。
这种行为也是一件好事。当它不应该是协变时,一个经典的例子是一个数组。下面的代码可以编译,但会在运行时失败:
void Bar()
{
// legal in C#:
object[] o = new string[10];
// fails with ArrayTypeMismatchException: can't store Int in a String[]
o[0] = 10;
}
实际上,'IEnumerable
@ FrancisR.Griffiths-Keam,你错了。从.NET 4开始,IEnumerable
@AnthonyPegram Ahh我错过了那个备忘录,谢谢你的记录。 – 2013-03-22 04:10:54
你的意思是你有一个列表''和功能'美孚(名单 C)'和'圈:IShape'?考虑'Foo'是否有'c.Add(new Square())'这一行。 –
2013-03-22 02:44:25
这是一个经常被问到的问题。搜索包含可枚举类型的协方差的问题。 – 2013-03-22 02:44:49
请问IEnumerable够用吗?并非所有类型都是协变的。 –
2013-03-22 02:45:21