2011-03-11 60 views
4

我在使用第三方庫時發現了這種行爲,我需要隱藏和更改其中一種方法。爲什麼一個子類需要實現一個父母界面來隱藏C#中父母方法之一?

我有以下設置:

interface IBaseInterface 
{ 
    string MethodToHide(); 
} 

class BaseClass : IBaseInterface 
{ 
    public string MethodToHide() 
    { 
     return "BaseClass"; 
    } 
} 

class ChildClass : BaseClass 
{ 
    new public string MethodToHide() 
    { 
     return "ChildClass"; 
    } 
} 

爲什麼當我運行以下命令:

var i = (IBaseInterface) (new ChildClass()); 
Console.WriteLine(i.MethodToHide()); 

輸出

BaseClass的

,但改變ChildClass簽名

class ChildClass : BaseClass, IBaseInterface 

時,輸出爲

ChildClass

爲什麼我需要明確指定接口的BaseClass的方法,通過隱藏ChildClass?

+0

hidden!=被覆蓋 – Greg 2011-03-11 18:43:28

回答

4

你需要閱讀更多的關於之間的區別覆蓋隱藏

鏈接:Override versus Hide

一言以蔽之:

隱藏(使用新)根據變量的類型運行該方法。
覆蓋將覆蓋該方法並只會使用該孩子的方法。

編輯

當你使用一個接口變量:

var i = (IBaseInterface) (new ChildClass()); 

編譯器將搜索對於那些接口使用方法的最佳匹配。
由於您聲明瞭BaseClass來實現該接口,因此將選擇其方法。

如果ChildClass沒有明確實現接口,則編譯器無法方法鏈接到該接口。以其觀點來看,BaseClass只是碰巧有同名的方法。

當你明確聲明,ChildClass也實現了接口,那麼它的方法將是最好的選擇。

+0

是的,但我對行爲感興趣,在這種情況下,我無法重寫該方法。在ChildClass的實例中,它被轉換爲接口,而不是基類。那麼爲什麼它是編譯器選擇的基類的方法呢? – 2011-03-11 18:51:46

+0

因爲編譯器的最佳選擇是顯式聲明方法屬於接口的BaseClass。從編譯器的角度來看,childclass恰好有一個同名的方法。 – 2011-03-11 18:55:10

+0

我已經添加了一些關於此的答案 – 2011-03-11 19:01:17

2

您需要在您的BaseClass中將MethodToHide標記爲虛擬。然後你的ChildClass可以覆蓋它。有關更多詳細信息,請參閱http://msdn.microsoft.com/en-us/library/9fkccyh4(v=vs.80).aspx

我相信這是規範的相關部分:

10.6.3虛擬方法在虛擬方法調用中,實例的運行時類型 針對該 調用發生確定 的實際方法實現爲 調用。在一個非虛方法 調用中,編譯時類型 該實例是確定 的因子。

所以,當你將原始對象投射到IBaseInterface。它確定類型是BaseClass,因爲那是實現它並調用它的方法的類型。在第二個示例中,它將其解析爲ChildClass並調用其方法。

+1

我相信OP是* explicity *詢問隱藏,而不是覆蓋。 – 2011-03-11 18:43:59

+0

因爲BaseClass是第三方封閉源庫的一部分,所以我無法做到這一點。而且我知道我可以這樣做,我正在詢問這種行爲。 – 2011-03-11 18:49:04

1

因爲主類實現了接口。子類只是定義了一個新的方法,與接口無關。事實上,孩子班級隱藏了這種方法 - 這就是「新」的做法。

相關問題