我有一个 Circle 对象数组(其中 Circle 实现了 IShape 接口,我有一个函数,其参数为......List<IShape>
为什么我不能将我的 Circles 数组传递给这个?
Visual Studio 给我一个构建错误,说无法转换List<Circle>
为List<IShape>
我有一个 Circle 对象数组(其中 Circle 实现了 IShape 接口,我有一个函数,其参数为......List<IShape>
为什么我不能将我的 Circles 数组传递给这个?
Visual Studio 给我一个构建错误,说无法转换List<Circle>
为List<IShape>
简短的回答是因为一个函数Foo
可以这样实现:
void Foo(IList<IShape> c)
{
c.Add(new Square());
}
如果您将 a 传递List<Circle>
给Foo
,则提供的类型将无法存储Square
,即使类型签名声称它是可以的。IList<T>
不是协变的:一般IList<Circle>
不能是 an,IList<IShape>
因为它不支持添加任意形状。
修复方法是用于IEnumerable<IShape>
接受 中的参数Foo
,但这并非在所有情况下都有效。IEnumerable<T>
是协变的:specializedIEnumerable<Circle>
符合 general 的契约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;
}