CLR 不支持协变返回类型,但它支持从 .NET 2.0 开始的委托/接口泛型变体。
换句话说,这并不是真正取决于 C# 团队,而是取决于 CLR 团队。
至于为什么 CLR 不支持正常方差 - 我不确定,除了增加复杂性之外,大概没有必要的感知收益量。
编辑:为了反驳关于返回类型协方差的观点,从 CLI 规范的第 8.10.4 节开始,谈论 vtable“插槽”:
对于标记为“期望现有槽”的每个新成员,查看是否存在类型(即字段或方法)、名称和签名的完全匹配,如果找到则使用该槽,否则分配一个新槽。
从分区 II,第 9.9 节:
具体来说,为了确定成员是否隐藏(对于静态或实例成员)或覆盖(对于虚拟方法)来自基类或接口的成员,只需将每个泛型参数替换为其泛型参数,并比较生成的成员签名。
没有迹象表明比较是以允许差异的方式进行的。
如果您认为 CLR确实允许差异,我认为鉴于上述证据,您可以使用一些适当的 IL 来证明它。
编辑:我刚刚在 IL 中尝试过,但它不起作用。编译这段代码:
using System;
public class Base
{
public virtual object Foo()
{
Console.WriteLine("Base.Foo");
return null;
}
}
public class Derived : Base
{
public override object Foo()
{
Console.WriteLine("Derived.Foo");
return null;
}
}
class Test
{
static void Main()
{
Base b = new Derived();
b.Foo();
}
}
运行它,输出:
Derived.Foo
拆开它:
ildasm Test.exe /out:Test.il
编辑Derived.Foo
以具有“字符串”而不是“对象”的返回类型:
.method public hidebysig virtual instance string Foo() cil managed
重建:
ilasm /OUTPUT:Test.exe Test.il
重新运行它,输出:
Base.Foo
换句话说,就 CLR 而言,Derived.Foo 不再覆盖 Base.Foo。