2009-09-24 61 views
1

在層次結構中,在某個點使用new關鍵字來覆蓋方法中的返回類型是否正常?C#中的新操作符和虛擬操作符

我可以使用virtual newnew virtual,這樣我可以重寫返回類型嗎?

我還需要考慮從那個點繼承的類。他們可以重寫這種方法,其基地是用new創建的?

回答

14

可以這樣做,但真正的問題是你是否應該做到這一點。

問題是,你會得到非常意想不到的行爲,這取決於你的類如何使用。如果你從基類的一個實例中調用你的類,原始的非「新」方法將被調用,這可能是意想不到的。

一般來說,我會避免使用new關鍵字來覆蓋基類方法,除非有非常明確的理由這樣做 - 如果您的方法將返回一個新類型,請將其聲明爲一個新方法一個不同的名稱或簽名,而不是隱藏基類方法 - 它會使您的層次更加可用。

+1

我完全同意。你應該有一個非常有說服力的理由這樣做。繼承關係是「IS A」關係,所以如果A從B繼承,那麼A就是B.這意味着A也應該表現得好像它是B. – Pete 2009-09-24 17:21:36

+0

我完全同意你的看法。我這樣做的原因是因爲我正在使用遺留代碼:(它是這樣做的,我可以改變它,我也不喜歡它,但我也是,我現在唯一確定的是它將使用所有將使用新類的地方,至少從聲明「新」類的地方調用 – jmayor 2009-09-24 17:43:08

+0

正如我所說,你可以這樣做 - 我個人會建議切換方法名,特別是儘管如此,避免這種情況,它使生活非常混亂。 – 2009-09-24 17:53:36

0

打趣....

public class BaseCollection<T> 
{ 
    // void return - doesn't seem to care about notifying the 
    // client where the item was added; it has an IndexOf method 
    // the caller can use if wants that information 
    public virtual void Add(T item) 
    { 
    // adds the item somewhere, doesn't say where 
    } 

    public int IndexOf(T item) 
    { 
    // tells where the item is 
    } 
} 

public class List<T> : BaseCollection<T> 
{ 
    // here we have an Int32 return because our List is friendly 
    // and will tell the caller where the item was added 
    new public virtual int Add(T item) // <-- clearly not an override 
    { 
    base.Add(item); 
    return base.IndexOf(item); 
    } 
} 

這裏我使用了「新」的修改,因爲列表<牛逼>參考將從BaseCollection <牛逼>隱藏Add方法。默認情況下,隱藏基本成員會從編譯器生成警告(如果編譯設置爲警告失敗,則爲錯誤)。所以我基本上是在告訴編譯器......「是的,我知道我使用void return隱藏了Add方法,它是所需的功能 - 只需要使用它。」