我有一个 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;
}