[英]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.