带有重写的C#重载 [英] C# overload with override
问题描述
我肯定可以自己编写一个虚拟测试来回答这个问题,但是我想知道人们对这个问题的看法.在这里:
I can surely answer to this question by myself writing a dummy test but I want to know what people think about the question. Here it is:
当我们同时具有重载和重载时,将调用哪个方法?我只考虑类型重载而不考虑Arity重载,并且当类型重载相关时.
Which method will be call when we have both at the same time overloading and overriding? I am only considering Type overloading and not arity overloading and when Type the overload are related.
让我举个例子:
class AA {}
class BB : AA {}
class A {
public virtual void methodA(AA anAA) { Console.Write("A:methodA(AA) called"); }
public virtual void methodA(BB aBB) { Console.Write("A:methodA(BB) called"); }
}
class B : A {
public override void methodA(AA anAA) { Console.Write("B:methodA(AA) called"); }
}
new B().methodA(new BB()); // Case 1
new B().methodA(new AA()); // Case 2
new B().methodA((AA)new BB()); // Case 3
您能说出情况1、2和3会发生什么吗?
Can you tell what will happen in case 1, 2, and 3?
我个人认为重载是邪恶的,没有一致的想法可以得出可预测的答案.这完全基于在compile + vm中实现的约定.
I personally think that overloadaing is evil and that there is no consistent thinking that could lead to a predictable answer. And that is completely base on a convention implemented in the compiler+vm.
If you have some doubt about why overload is evil you can read the blog post from Gilad Brach
谢谢
推荐答案
当编译器确定要调用的方法时,重写的方法将从方法集中排除.请参见成员查找算法.因此,当您在类型B
上调用methodA
时,将构造类型为B
且名称为methodA
的成员集,它的基本类型将是:
Overridden methods are excluded from method set when compiler determines which method to call. See member lookup algorithm. So, when you call methodA
on type B
, set of members with name methodA
from type B
and it's base type will be constructed:
override B.methodA(AA)
virtual A.methodA(AA)
virtual A.methodA(BB)
然后将具有ovveride
修饰符的成员从集合中删除:
Then members with ovveride
modifier removed from set:
virtual A.methodA(AA)
virtual A.methodA(BB)
这组方法是查找的结果.之后,过载分辨率用于定义哪个成员调用.
This group of methods is the result of lookup. After that overload resolution applied to define which member to invoke.
-
A.methodA(BB)
被调用,因为其参数与参数匹配. -
A.methodA(AA)
将被选择,但是它是虚拟方法,因此实际调用转到B.method(AA)
- 与选项2相同
A.methodA(BB)
is invoked, because its argument matches parameter.A.methodA(AA)
will be chosen, but it is virtual method, so actually call goes toB.method(AA)
- Same as option 2
这篇关于带有重写的C#重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!