基类构造函数和初始化器的执行顺序!

王朝学院·作者佚名  2010-01-14  
宽屏版  字体: |||超大  

标题比较抽象,所以我写了一个Demo来说明问题:

public class A

{

public A()

{

Console.WriteLine("A的构造函数被调用");

}

}

public class B : A

{

private X x = new X(); //初始化器

}

public class X

{

public X()

{

Console.WriteLine("X的构造函数调用");

}

}

static void Main(string[] args)

{

B b = new B();

}

在调用子类的构造函数之前,会先调用基类的构造函数,那初始化器和基类的构造函数到底谁先执行呢?

因为初始化代码会在构造函数中的代码之前执行,所以我过去错误的认为:

public class B : A

{

private X x = new X(); //初始化器

}

等价于:

public class B : A

{

private X x;

public B()

{

x=new X();

}

}

所以我也错误的认为基类的构造函数是在子类的初始化器之前执行的,上面的Demo执行的结果刚好相反,是:

X的构造函数调用

A的构造函数被调用

这表明子类的构造器先执行了,让我们看看生成的构造函数的IL代码:

public class B:A

{

private X x;

public B()

{

x = new X();

}

}

生成的构造函数的IL代码是这样的:

.method public hidebysig specialname rtspecialname

instance void .ctor() cil managed

{

// 代码大小 21 (0x15)

.maxstack 8

IL_0000: ldarg.0

IL_0001: call instance void ConsoleApplication1.Program/A::.ctor()

IL_0006: nop

IL_0007: nop

IL_0008: ldarg.0

IL_0009: newobj instance void ConsoleApplication1.Program/X::.ctor()

IL_000e: stfld class ConsoleApplication1.Program/X ConsoleApplication1.Program/B::x

IL_0013: nop

IL_0014: ret

} // end of method B::.ctor

从代码可以看出是先调用基类的构造函数的!

public class B : A

{

private X x = new X();

}

生成的构造函数的IL代码是这样的:

.method public hidebysig specialname rtspecialname

instance void .ctor() cil managed

{

// 代码大小 19 (0x13)

.maxstack 8

IL_0000: ldarg.0

IL_0001: newobj instance void ConsoleApplication1.Program/X::.ctor()

IL_0006: stfld class ConsoleApplication1.Program/X ConsoleApplication1.Program/B::x

IL_000b: ldarg.0

IL_000c: call instance void ConsoleApplication1.Program/A::.ctor()

IL_0011: nop

IL_0012: ret

} // end of method B::.ctor

可以看出是先调用初始化器的代码,然后再调用基类构造函数的!可见使用初始化器和不使用初始化器还是有区别的,主要区别是基类构造函数的调用顺序不同!

C#编译器为什么这样设计,我也没有想到太合理的原因,大家有什么看法呢?

请大家多多指教啊!

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
© 2005- 王朝网络 版权所有