2013-05-11 71 views
3

那麼,最初我有幾個常量(如MAX_SPEED)在每個派生類中都有不同的值。這個想法是在基類的某些方法中使用這些值。那時候我意識到我不能用常量來做到這一點,所以我創建了只讀屬性。調用派生類的構造函數在基類的構造函數之前執行

我需要一種方法將這些值分配給實例化時的私有字段,最好在基類中。但首先我必須在派生類中分配原始值。由於這些是屬性,我無法在定義時找到初始化它們的方法,所以唯一的方法是在派生的構造函數中。

這就是問題出現的地方:值在分配給基類中的私有字段後被初始化。我擺脫的解決方案是創建一個虛擬方法並在那裏進行分配。

有沒有辦法從派生類調用基礎構造函數,以便從派生的構造函數的代碼將被首先調用?

class BaseClass 
{ 
    public BaseClass() 
    { 
     System.Console.WriteLine("This should be shown after"); 
    } 
} 

class DerivedClass : BaseClass 
{ 
    public DerivedClass() : base() 
    { 
     System.Console.WriteLine("This should be shown first"); 
    } 
} 

當然在這個例子中,它會以相反的方式工作。有解決方案嗎?

+0

不需要。您必須先調用基礎構造函數,如果不這樣做,則會出現錯誤。順便說一句你爲什麼要這個? – ppetrov 2013-05-11 15:48:59

+0

我在Jon的回答評論中描述了這種情況。我想我應該在問題中說清楚。 – msgmaxim 2013-05-12 11:45:05

回答

12

否基類構造函數是總是在派生類構造函數的主體之前執行。但是:在派生類

  • 任何實例變量初始化被執行之前基類構造
  • 基類的構造可以執行可在派生類中重寫虛擬方法。 雖然這幾乎總是一個壞主意。(各種正常的前提條件是在這一點上無效。你可以觀察已尚未設置,因爲他們會在構造函數體中設置只讀變量,例如,伊克)

爲了證明這兩種:

using System; 

class BaseClass 
{ 
    public BaseClass() 
    { 
     VirtualMethod(); 
     Console.WriteLine("BaseClass ctor body"); 
    } 

    public virtual void VirtualMethod() 
    { 
     Console.WriteLine("BaseClass.VirtualMethod"); 
    } 
} 

class DerivedClass : BaseClass 
{ 
    int ignored = ExecuteSomeCode(); 

    public DerivedClass() : base() 
    { 
     Console.WriteLine("DerivedClass ctor body"); 
    } 

    static int ExecuteSomeCode() 
    { 
     Console.WriteLine("Method called from initializer"); 
     return 5; 
    } 

    public override void VirtualMethod() 
    { 
     Console.WriteLine("DerivedClass.VirtualMethod"); 
    } 
} 

class Test 
{ 
    static void Main() 
    { 
     new DerivedClass(); 
    } 
} 

輸出:

Method called from initializer 
DerivedClass.VirtualMethod 
BaseClass ctor body 
DerivedClass ctor body 

此外,如果你的基類的構造函數需要一個參數,那麼你可以在派生類中,以提供AR執行一些代碼所有這些都相當臭。但是,這些都是相當臭。你的具體情況是什麼?

+0

好吧,最初我有幾個常量(如MAX_SPEED)在每個派生類中具有不同的值。這個想法是在基類的某些方法中使用這些值。那時候我意識到我不能用常量來做到這一點,所以我創建了只讀屬性。 – msgmaxim 2013-05-12 11:42:40

+0

我需要一個方法來在實例化時將這些值賦給私有字段,最好是在基類中。但首先我必須在派生類中分配原始值。由於這些是屬性,我無法在定義時找到初始化它們的方法,所以唯一的方法是在派生的構造函數中。 – msgmaxim 2013-05-12 11:43:05

+0

這就是問題出現的地方:值在分配給基類中的私有字段後被初始化。 我得到的解決方案是(如你所說)創建一個虛擬方法並在那裏進行分配。 – msgmaxim 2013-05-12 11:43:25

7

不,你不能那樣做。基類始終首先被初始化。然而,你可以做這樣的事情:

class BaseClass 
{ 
    public BaseClass() 
    { 
     this.Initialize(); 
    } 

    protected virtual void Initialize() 
    { 
     System.Console.WriteLine("This should be shown after"); 
    } 
} 

class DerivedClass : BaseClass 
{ 
    public DerivedClass() : base() 
    { 
    } 

    protected override void Initialize() 
    { 
     System.Console.WriteLine("This should be shown first"); 
     base.Initialize(); 
    } 
} 
+0

這正是我在構造函數失敗後在真正的程序中所做的!不管怎樣,謝謝你! – msgmaxim 2013-05-12 11:14:57

0

還有一個選擇是讓子類構造函數靜態的,因此它首先執行比父類的構造。但它不是優選的,它違反了oop設計

相關問題