说我有这个类:构造函数链优先
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