方法超载分辨率和Jon Skeet的Brain Teasers

乔恩的脑筋急转弯

这里是剧透……

我正在看#1的答案 ,我必须承认我从来不知道重载决议是这种情况。 但为什么这样呢。 在我的小脑海中, Derived.Foo(int)似乎是合乎逻辑的路线。

这个设计决定背后的逻辑是什么?

奖金时间!

此行为是C#规范,CLR实现还是编译器的结果?

这种行为是经过深思熟虑和精心设计的。 原因是因为这种选择减轻了一种forms的脆性基类失效的影响。

阅读有关该主题的文章了解更多详情。

http://blogs.msdn.com/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx

这是一个可能的解释:

当编译器链接方法调用时,它首先查找inheritance链中最低的类(在本例中为Derived类)。 它的实例方法被检查和匹配。 重写方法Foo不是Derived的实例方法,它是Base类的实例方法。

正如Jack30lena提出的那样,原因可能是性能,但它也可能是编译器如何解释编码器的意图。 可以肯定的是,开发人员的预期代码行为位于inheritance链底部的代码中。

这是编译器的结果,我们检查了IL代码。

原因是因为它含糊不清。 编译器只需要决定一个。 并且有人认为间接性越小越好(性能可能是一个原因)。 如果开发人员刚刚写道:

 ((Base)d).Foo (i); 

它很清楚,并给你预期的结果。

原因是:表现。 调用虚方法需要更多时间。 在虚拟方法上调用委托需要更多时间等等….

请参阅: 方法调用的成本