[英]C# overload with override
我肯定可以自己编写一个虚拟测试来回答这个问题,但我想知道人们对这个问题的看法。 这里是:
当我们同时具有重载和重载时,将调用哪个方法? 我只考虑Type重载而不考虑Arity重载,而当Type重载相关时。
让我举个例子:
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会发生什么吗?
我个人认为重载是邪恶的,没有一致的想法可以得出可预测的答案。 这完全基于在compile + vm中实现的约定。
编辑:如果您对为什么超载是邪恶有疑问,可以阅读Gilad Brach的博客文章。
谢谢
不,这是完全可以预见的。 首先解决方法签名-即首先确定重载 。 然后,最重写的方法被调用。 因此输出将是:
在后两种情况下,将调用采用AA实例的方法,因为这是传入的引用的类型,并且它是B的版本。 请注意,即使这样也会产生相同的结果:
A instance = new B();
instance.methodA((AA)new BB()); // Case 3
当编译器确定要调用哪个方法时,重写的方法将从方法集中排除。 请参阅成员查找算法。 因此,当您在类型B
上调用methodA
时,将构造类型B
且名称为methodA
的成员集,该成员集是其基本类型:
override B.methodA(AA)
virtual A.methodA(AA)
virtual A.methodA(BB)
然后从集合中删除具有ovveride
修饰符的成员:
virtual A.methodA(AA)
virtual A.methodA(BB)
这组方法是查找的结果。 之后,应用重载解析来定义要调用的成员。
A.methodA(BB)
,因为它的参数匹配参数。 A.methodA(AA)
,但它是虚拟方法,因此实际调用转到B.method(AA)
我认为结果将是这样
情况1:Console.Write(“ A:methodA(BB)被称为”);
情况2:Console.Write(“ B:methodA(AA)被称为”);
情况3:Console.Write(“ B:methodA(AA)被称为”);
在情况3中,它将看起来像是传递的类型,它是B
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.