簡體   English   中英

帶有重寫的C#重載

[英]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的博客文章。

謝謝

不,這是完全可以預見的。 首先解決方法簽名-即首先確定重載 然后,最重寫的方法被調用。 因此輸出將是:

  • A:methodA(BB)被稱為
  • B:方法A(AA)稱為
  • B:方法A(AA)稱為

在后兩種情況下,將調用采用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)

這組方法是查找的結果。 之后,應用重載解析來定義要調用的成員。

  1. 調用A.methodA(BB) ,因為它的參數匹配參數。
  2. 將選擇A.methodA(AA) ,但它是虛擬方法,因此實際調用轉到B.method(AA)
  3. 與選項2相同

我認為結果將是這樣

情況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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM