为什么类型约束不是方法签名的一部分?

Dar*_*ryl 9 c# generics type-constraints overload-resolution nested-generics

所以我读了Eric Lippert的'Constraints不是签名的一部分',现在我明白规范指定在重载解析后检查类型约束,但我仍然不清楚为什么必须如此.以下是Eric的例子:

static void Foo<T>(T t) where T : Reptile { }
static void Foo(Animal animal) { }
static void Main() 
{ 
    Foo(new Giraffe()); 
}
Run Code Online (Sandbox Code Playgroud)

这不会编译,因为重载解析:Foo(new Giraffe())推断Foo<Giraffe>是最好的重载匹配,但是类型约束失败并抛出编译时错误.用埃里克的话说:

这里的原则是重载决策(和方法类型推断)找到参数列表和每个候选方法的形式参数列表之间的最佳匹配.也就是说,他们会查看候选方法的签名.

类型约束不是签名的一部分,但为什么不能呢?在某些情况下,考虑类型约束是签名的一部分是个坏主意吗?实施起来困难还是不可能?我并不是在提倡如果最佳选择的超载是出于无论什么原因无法调用的话,那么就会默默地回归到第二好的; 我讨厌那个.我只是想了解为什么不能使用类型约束来影响最佳过载的选择.

我想象在C#编译器内部,仅用于重载解析(它不会永久重写方法),如下所示:

static void Foo<T>(T t) where T : Reptile { }
Run Code Online (Sandbox Code Playgroud)

变成了:

static void Foo(Reptile  t) { }
Run Code Online (Sandbox Code Playgroud)

为什么不能将类型约束"拉入"形式参数列表?这怎么会以任何不好的方式改变签名?我觉得它只会加强签名.然后Foo<Reptile>永远不会被视为超载候选者.

编辑2:难怪我的问题太混乱了.我没有正确阅读Eric的博客,我引用了错误的例子.我在示例中编辑了我觉得更合适.我还将标题更改为更具体.这个问题似乎并不像我最初想象的那么简单,也许我错过了一些重要的概念.我不太确定这是stackoverflow材料,这个问题/讨论可能最好转移到其他地方.

Fal*_*nwe 5

C#编译器不必将类型约束视为方法签名的一部分,因为它们不是CLR的方法签名的一部分.如果重载工作中为不同的语言(主要是动态绑定由于可在运行时发生,不应该是从一种语言不同到另一个,否则所有的地狱将打破松散),这将是灾难性的.

为什么决定这些约束不会成为CLR方法签名的一部分又是另一个问题,我只能对此做出不明智的假设.我会让知情人回答这个问题.