以下代码无法编译(使用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
    }
}

编译器给出两个错误:

最佳答案

您要尝试执行的操作称为covariance-从较窄的类型(TestClass)转换为较宽的类型(ITest)。这是您一直都会习惯的事情,例如,当您从浮点数转换为 double 数时,就会发生这种情况。

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

.Net 4.0现在确实支持泛型中的协方差(和逆方差),前提是这些泛型类使用协变量类型的关键字out和协变类型的关键字in进行编译。 .Net 4.0中的IEnumerable定义为协变。如果右键单击IEnumerable类型并单击“goto definition”,您将看到以下内容:

public interface IEnumerable<out T> : IEnumerable

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

MSDN has more information

10-04 14:34
查看更多