0

我有一个 Circle 对象数组(其中 Circle 实现了 IShape 接口,我有一个函数,其参数为......List<IShape>为什么我不能将我的 Circles 数组传递给这个?

Visual Studio 给我一个构建错误,说无法转换List<Circle>List<IShape>

4

1 回答 1

5

简短的回答是因为一个函数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;
}
于 2013-03-22T02:52:16.643 回答