C#编译器无法识别一个类正在实现一个接口

以下代码无法编译(使用VS2010),我不明白为什么.编译器应该能够推断出List&TestClass>对于IEnumerable< ITest>而言,它是“兼容的”(对于缺乏更好的词语而感到遗憾),但不知何故.我在这里缺少什么?

interface ITest {
    void Test();
}


class TestClass : ITest {
    public void Test() {
    }
}

class Program {
    static void Test(IEnumerable<ITest> tests) {
        foreach(var t in tests) {
            Console.WriteLine(t);
        }
    }
    static void Main(string[] args) {
        var lst = new List<TestClass>();

        Test(lst); // fails, why?

        Test(lst.Select(t=>t as ITest)); //success

        Test(lst.ToArray()); // success
    }
}

编译器给出两个错误:

  1. The best overloaded method match for ‘ConsoleApplication1.Program.Test(System.Collections.Generic.IEnumerable<ConsoleApplication2.ITest>)’ has some invalid arguments

  2. Argument 1: cannot convert from ‘System.Collections.Generic.List<ConsoleApplication2.TestClass>’ to ‘System.Collections.Generic.IEnumerable<ConsoleApplication2.ITest>’

最佳答案
您尝试做的是称为covariance – 从较窄类型(TestClass)转换为更广泛类型(ITest).这是你一直习惯的东西,例如当你从一个浮点数转换为一个double时就会发生.

不幸的是,.NET 3.5及更低版本不支持泛型类中的协方差.

.Net 4.0现在支持泛型的协方差(和逆变),只要这些泛型类型用于协变类型的关键字编译,并且用于违规类型. .Net 4.0中的IEnumerable被定义为协变量.如果您右键单击IEnumerable类型并单击“goto definition”,您将看到:

public interface IEnumerable<out T> : IEnumerable

如果您使用的是VS2010,则需要确保您的项目的目标是.net 4.0.这可以从项目属性更改.右键单击项目,选择属性,转到“应用程序”选项卡,并检查“目标框架”到.Net 4.

MSDN has more information.

转载注明原文:C#编译器无法识别一个类正在实现一个接口 - 代码日志