方法超载分辨率和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);
它很清楚,并给你预期的结果。
原因是:表现。 调用虚方法需要更多时间。 在虚拟方法上调用委托需要更多时间等等….
请参阅: 方法调用的成本