說我有這個類:構造函數鏈優先
class FooBar
{
public FooBar() : this(0x666f6f, 0x626172)
{
}
public FooBar(int foo, int bar)
{
...
}
...
}
如果我這樣做:
FooBar foobar = new FooBar();
將非參數的構造函數執行第一,然後是參數之一,或者是它的另一怎麼辦?
說我有這個類:構造函數鏈優先
class FooBar
{
public FooBar() : this(0x666f6f, 0x626172)
{
}
public FooBar(int foo, int bar)
{
...
}
...
}
如果我這樣做:
FooBar foobar = new FooBar();
將非參數的構造函數執行第一,然後是參數之一,或者是它的另一怎麼辦?
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
所以參數的構造函數執行顯式調用一個之前。
到最後一個代碼示例:當然,即使_before_「second」被打印出來,base()構造函數也會運行,這就是基類「System.Object」的零參數實例構造函數。 –
控件將首先到達默認構造函數。由於我們從那裏調用了參數化構造函數,所以默認構造函數中的語句執行將停止,控件將移至參數化構造函數。一旦參數化構造函數中的語句執行完成,控件將移回到默認構造函數。
您可以通過在默認構造函數中放置一個斷點來驗證它。
首先初始化類變量,然後鏈接構造函數,然後在默認構造函數的大括號之間進行編碼。 – Ruben
不知道這是否記錄爲「已定義的行爲」,但TestClass(int)
先執行,然後執行TestClass()
。
通過構造函數的調用無關與構造是默認或非默認的(參數化),而是通過級聯關係決定的順序。
詳細地講,後面跟着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
對所有那些投票關閉這個問題作爲[C#構造函數執行順序]的確切副本(http://stackoverflow.com/questions/1882692/c-sharp-constructor-execution-order):它不是。鏈接的問題詢問「base」關鍵字;這個問題是關於'this'關鍵字的。 – Douglas