2012-07-18 91 views
-1

我想要在基類中定義一個字段,該字段將影響屬於基類的對象的創建。但是,我希望能夠覆蓋該字段的值,之前調用基類cto'r。舉個例子:在基類中使用派生類的字段在c#中

class ObjNeedParam 
{ 
    public ObjNeedParam(int p) 
    { 
     val = p; 
    } 
    int val; 
    int Value{get{return Value;}} 
} 
class Base 
{ 
    public Base() 
    { 
     obj = new ObjNeedParam(paramVal); 
    } 
    ObjNeedParam obj; 
    protected int paramVal = 1; 
} 

class Derived : Base 
{ 
    public Derived() 
    { 
     //Once I'm here, obj has already been created with paramVal=1 instead of 2!    
     dummy = 3; 
    } 
    new int paramVal = 2; 
    int dummy; 
} 
+0

使paramval虛擬屬性,並覆蓋它 – 2012-07-18 09:34:39

+0

你將不得不將價值傳遞給基礎構造函數 – V4Vendetta 2012-07-18 09:35:00

+1

我理解的問題和答案 - 我不明白的是2 downvotes ...你爲什麼downvote沒有在這種情況下發表評論? – Carsten 2012-07-18 09:37:26

回答

3

這種做法是有點懷疑,所以你可能想在這裏重新考慮你的方法。

如果你還是想用這個去未來,正確的方法是有一個virtual方法提供該值基本構造:

class Base 
{ 
    public Base() 
    { 
     obj = new ObjNeedParam(GetParamVal()); 
    } 

    protected virtual int GetParamVal() { return 1; } 
} 

class Derived : Base 
{ 
    protected override int GetParamVal() { return 2; } 
} 

你必須確保override不使用在Derived的構造函數中初始化的Derived的任何類成員,因爲該構造函數在調用覆蓋的地方尚未運行!請參閱Virtual member call in a constructor

更新:這是有點懷疑,因爲建造一些派生類型的對象時,編譯器有問題要解決:在什麼樣的順序應該等領域進行初始化和構造函數運行,以便從任何構造函數內的任何方法調用保證能找到處於「可用」狀態的對象?

這個問題不能在一般情況下可以解決,因爲根據定義的對象不是處於可用狀態,直到所有構造都回來了,我們都在談論從調用這些構造方法。因此,編譯器必須儘可能保證能夠阻止或允許您執行不可證實的安全事情。

在這種情況下,C++(有趣的)阻止了那些不可證實的事情,而C#卻允許這樣做。因此,如果您不注意,可能會引入錯誤,這是有點可疑的。一種更安全的方法是編寫該類,以便在構造函數運行後對該成員進行初始化。

+0

太棒了,這個作品!但請您詳細說明「有些可疑」的問題嗎?如果這不是正確的路,我想知道爲什麼。謝謝! – zuuz 2012-07-18 09:38:55

+0

@zorbar:更新了答案,看一看。 – Jon 2012-07-18 10:26:40

+0

我明白了。 Thx很詳細的解釋。 – zuuz 2012-07-18 11:22:32

1

你需要做的是而不是以這種方式初始化該字段。一種替代方法是將該字段設置爲屬性,並允許子類重寫。另外,允許外地在通過參數的基類的構造函數來設置,所以你可以寫這樣的代碼:

class Base 
{ 
    public Base() : this(1) 
    { 
    } 

    public Base(int param) 
    { 
     paramVal = param; 
    } 

    private int paramVal; 
} 

class Derived : Base 
{ 
    public Derived() : base(2) 
    { 
    } 
} 

最終,場通常是私人一類,並且是永遠不會被覆寫投放派生類。如果你想暴露它的派生類來操縱,那麼你可能想要的東西不是字段。

相關問題