2011-07-22 58 views
10

考慮代碼重載決策

public class Base 
{ 
    public virtual int Add(int a,int b) 
    { 
     return a+b; 
    } 
} 

public class Derived:Base 
{ 
    public override int Add(int a,int b) 
    { 
     return a+b; 
    } 

    public int Add(float a,float b) 
    { 
     return (Int32)(a + b); 
    } 
} 

如果我創建派生類的實例,並調用添加與它爲什麼調用帶有浮動參數的Add方法int類型的參數

Derived obj =new Derived() 
obj.Add(3,5) 

// why this is calling 
Add(float a,float b) 

爲什麼不調用更具體的方法?

+1

你怎麼知道3和5是int?嘗試指定他們的類型,看看會發生什麼。 –

+0

你怎麼知道它是? –

+0

你能編譯這個嗎?你可能會得到一些類似float的類型轉換錯誤嗎? – Anuraj

回答

15

這是設計。 C#語言規範狀態的第7.5.3節:

例如,用於集合的方法調用的候選不包括標記方法倍率(§7.4),並在一個基類的方法都沒有候選如果任何方法在派生類中是適用的(第7.6.5.1節)。

換句話說,因爲你Derived類具有非重寫Add方法,在Base類(和Derived其重寫版本)的Add方法不再是超負荷分辨率候選。

儘管Base.Add(int,int)會更好地匹配,但Derived.Add(float,float)的存在意味着基類方法甚至從不被編譯器考慮。

Eric Lippert在this blog post中討論了此設計的一些原因。

+0

+1好答案。證明,解釋和進一步閱讀的鏈接。 – Matt

+0

有沒有辦法在保持原始方法可見的同時爲虛擬方法添加重載? – supercat