2012-06-02 86 views
2

說我有這個類:構造函數鏈優先

class FooBar 
{ 
    public FooBar() : this(0x666f6f, 0x626172) 
    { 
    } 

    public FooBar(int foo, int bar) 
    { 
     ... 
    } 
... 
} 

如果我這樣做:

FooBar foobar = new FooBar(); 

將非參數的構造函數執行第一,然後是參數之一,或者是它的另一怎麼辦?

+2

對所有那些投票關閉這個問題作爲[C#構造函數執行順序]的確切副本(http://stackoverflow.com/questions/1882692/c-sharp-constructor-execution-order):它不是。鏈接的問題詢問「base」關鍵字;這個問題是關於'this'關鍵字的。 – Douglas

回答

5

MSDN有類似的例子與base

public class Manager : Employee 
{ 
    public Manager(int annualSalary) 
     : base(annualSalary) 
    { 
     //Add further instructions here. 
    } 
} 

並指出:

在本例中,執行用於構造塊 之前基類的構造函數被調用。

不過,可以肯定的,這裏是我的測試:

class Program 
{ 
    public Program() : this(0) 
    { 
     Console.WriteLine("first"); 
    } 

    public Program(int i) 
    { 
     Console.WriteLine("second"); 
    } 

    static void Main(string[] args) 
    { 
     Program p = new Program(); 
    } 
} 

打印

second 
first 

所以參數的構造函數執行顯式調用一個之前。

+0

到最後一個代碼示例:當然,即使_before_「second」被打印出來,base()構造函數也會運行,這就是基類「System.Object」的零參數實例構造函數。 –

3

控件將首先到達默認構造函數。由於我們從那裏調用了參數化構造函數,所以默認構造函數中的語句執行將停止,控件將移至參數化構造函數。一旦參數化構造函數中的語句執行完成,控件將移回到默認構造函數。

您可以通過在默認構造函數中放置一個斷點來驗證它。

+3

首先初始化類變量,然後鏈接構造函數,然後在默認構造函數的大括號之間進行編碼。 – Ruben

1

不知道這是否記錄爲「已定義的行爲」,但TestClass(int)先執行,然後執行TestClass()

1

通過構造函數的調用無關與構造是默認非默認的(參數化),而是通過級聯關係決定的順序。

詳細地講,後面跟着this關鍵字的每個構造函數都會暫停並跳轉到this關鍵字指向的構造函數。當到達最後一個鏈式構造函數時,它的代碼就會運行。然後程序運行鏈中的前一個構造函數,這將一直回到第一個。

一個例子可以說明這一點。

假設一個類中你有3個構造函數如下:

public class Test 
{ 
    public Test() : this(5) 
    { 
     Console.WriteLine("no params"); 
    } 

    public Test(int i) : this("Hi") 
    { 
     Console.WriteLine("integer=" + i.ToString()); 
    } 

    public Test(string str) 
    { 
     Console.WriteLine("string=" + str); 
    } 
} 

如果調用默認的構造函數var t = new Test(),你會看到下面的輸出:

// string=Hi -> The last .ctor 
// integer=5 -> Second .ctor 
// no params -> First .ctor