为什么.Net 4不允许我传入一个接口数组?

leo*_*ora 0 c# collections covariance

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

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

Tra*_*kel 5

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

void Foo(IList<IShape> c)
{
    c.Add(new Square());
}
Run Code Online (Sandbox Code Playgroud)

如果您传递了一个List<Circle>to 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;
}
Run Code Online (Sandbox Code Playgroud)

  • @ FrancisR.Griffiths-Keam,你错了.从.NET 4开始,IEnumerable <T>在T上是协变的,这意味着只要X派生自(或实现)T,就可以替换IEnumerable <X>. (2认同)