2011-05-16 38 views
1

這更像是一個「有更好的方式」問題,而不是真正的問題。繼承常量 - 最佳風格?

即有可能僅在一個基類訪問屬性:

private const bool isSomething = true; 

我有時在我從這個類繼承的一個項目更改此值。但是,因爲它是一個常數,使用類範圍的,我通常在基類中的代碼更改爲類似這樣:

private const bool isSomething = true; 
protected virtual bool IsSomething{ 
     get{ 
      return isSomething; 
     } 
} 

,並覆蓋子類中的屬性,並創建一個新的isSomething不變。

這創造了一個新的領域和覆蓋,在我看來,不是很好的風格。有一個更好的方法嗎?

該值是一個常數,並且在我使用它的完整項目中它將保持不變。

+0

因此無處不在需要您調用IsSomething()而不是? – n8wrl 2011-05-16 20:37:49

+0

@ n8wrl:是的,這是我目前的解決方法,用於覆蓋整個類的常量。 – Michael 2011-05-16 20:44:31

+0

看起來像基類中只讀受保護屬性的完美候選者,不需要虛擬/覆蓋。 – 2011-05-17 00:37:26

回答

3

如果您需要根據您所在的班級設置值,但不希望稍後再更改此值,那麼const不是正確的關鍵字。相反,您可以使用readonly並要求子類將值傳遞給構造函數。

readonly關鍵字與const關鍵字不同。 const字段只能在字段的聲明處初始化。只讀字段可以在聲明或構造函數中初始化。因此,只讀字段可以具有不同的值,具體取決於所使用的構造函數。此外,雖然常量字段是一個編譯時間常數,只讀域可用於運行時常... Source

編輯:
總結:你有申請即只訪問由基類和基類決不應該改變這個值。在大多數情況下,默認值是好的。但是,當某個子類需要設置與默認值不同的值時,會出現一些情況。

class Base { 
    private readonly bool _isSomething; 

    public Base() : this(false) {} 

    protected Base(bool isSomething) 
    { 
    _isSomething = isSomething; 
    } 
} 
class Child { 
    public Child() : base(true) {} 
} 

這提供了與建議的解決方法相同的功能。該值不能改變,只有子類可以提供不同的值。它還有一個額外的好處,就是不允許孩子班級使這個值不變的事實失效。覆蓋方法允許這樣的:

protected override bool IsSomething{ 
    get{ 
    return BOOLEAN_EXPRESSION; 
    } 
} 

我理解你使它成爲一個靜態值(因爲我們知道每一個實例都將使用相同的值)的想法,但這隻會使事情複雜,因爲靜態項不能被繼承。

+0

它在哪個項目中,而不是在哪個類中,因此它將是靜態只讀。但是靜態只讀不能從我測試過的繼承類中設置。 – Michael 2011-05-16 20:56:30

+0

@Michael:查看我的編輯,瞭解我的意思。 – unholysampler 2011-05-16 21:35:26

+0

好吧,有一個靜態標誌可能是主要問題,因爲我不想創建一個程序實例中值可以具有不同設置的印象。但這至少是我可以根據情況選擇的一種選擇。 – Michael 2011-05-16 22:13:41