为什么. net 4不允许我传入接口的数组?

本文关键字:接口 数组 net 不允许 允许我 为什么 | 更新日期: 2023-09-27 18:05:19

我有一个Circle对象数组(其中Circle实现了isshape接口,并且我有一个函数具有List<IShape>的参数)。为什么我不能把我的圆圈数组传递给这个呢?

Visual studio给了我一个构建错误说不能将List<Circle>转换为List<IShape>

为什么. net 4不允许我传入接口的数组?

简短的回答是因为Foo函数可以这样实现:

void Foo(IList<IShape> c)
{
    c.Add(new Square());
}

如果您将List<Circle>传递给Foo,则提供的类型将无法存储Square,即使类型签名声明它是可以的。IList<T>不是协变的:一般的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;
}