C# 构造函数调用顺序

了解C#的一个类的加载过程,对于语言机制的理解和写出高效的语言很有帮助,这里简单介绍一下类的实例的构造函数调用过程。
C#类的实例的构造过程是,先为实例的数据字段分配内存,并对所有字段按字节置零(0或者null);然后初始化附加内存(类型对象指针和同步块索引);调用类型的实例构造器(也就是new关键字调用的普通构造函数)初始化字段。
假如有两个类:基类BaseClass和派生类DerivedClass。DerivedClass继承BaseClass。

 1 namespace GenericSyntax.Constructor
 2 {
 3     class BaseClass
 4     {
 5         public BaseClass()
 6         {
 7             Console.WriteLine("Base class Ctor.");
 8         }
 9     }
10 
11     class DerivedClass:BaseClass
12     {
13         private string m_Var1 = "Assigned in declaration.";
14         private string m_Var2;
15         public DerivedClass()
16         {
17             Console.WriteLine(m_Var2==null);
18             Console.WriteLine(m_Var1);
19             m_Var1 = "Assigned in constructor of derived Class.";
20             Console.WriteLine("Derived class Ctor.");
21         }
22         public override string ToString()
23         {
24             return m_Var1;
25         }
26     }
27 }
28 namespace GenericSyntax
29 {
30     class Program
31     {
32         static void Main(string[] args)
33         {
34             TestCtor();
35             Console.ReadKey();
36         }
37         private static void TestCtor()
38         {
39             Constructor.DerivedClass instance = new             
40             Constructor.DerivedClass();
41             Console.WriteLine(instance.ToString());
42         }
43     }
44 }        

生成的BaseClass的IL和DerivedClass的IL如下:

 1 .method public hidebysig specialname rtspecialname 
 2         instance void  .ctor() cil managed
 3 {
 4   // 代码大小       20 (0x14)
 5   .maxstack  8
 6   IL_0000:  ldarg.0
 7   IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
 8   IL_0006:  nop
 9   IL_0007:  nop
10   IL_0008:  ldstr      "Base class Ctor."
11   IL_000d:  call       void [mscorlib]System.Console::WriteLine(string)
12   IL_0012:  nop
13   IL_0013:  ret
14 } // end of method BaseClass::.ctor
 1 .method public hidebysig specialname rtspecialname 
 2         instance void  .ctor() cil managed
 3 {
 4   // 代码大小       69 (0x45)
 5   .maxstack  2
 6   IL_0000:  ldarg.0
 7   IL_0001:  ldstr      "Assigned in declaration."
 8   IL_0006:  stfld      string GenericSyntax.Constructor.DerivedClass::m_Var1
 9   IL_000b:  ldarg.0
10   IL_000c:  call       instance void GenericSyntax.Constructor.BaseClass::.ctor()
11   IL_0011:  nop
12   IL_0012:  nop
13   IL_0013:  ldarg.0
14   IL_0014:  ldfld      string GenericSyntax.Constructor.DerivedClass::m_Var2
15   IL_0019:  ldnull
16   IL_001a:  ceq
17   IL_001c:  call       void [mscorlib]System.Console::WriteLine(bool)
18   IL_0021:  nop
19   IL_0022:  ldarg.0
20   IL_0023:  ldfld      string GenericSyntax.Constructor.DerivedClass::m_Var1
21   IL_0028:  call       void [mscorlib]System.Console::WriteLine(string)
22   IL_002d:  nop
23   IL_002e:  ldarg.0
24   IL_002f:  ldstr      "Assigned in constructor of derived Class."
25   IL_0034:  stfld      string GenericSyntax.Constructor.DerivedClass::m_Var1
26   IL_0039:  ldstr      "Derived class Ctor."
27   IL_003e:  call       void [mscorlib]System.Console::WriteLine(string)
28   IL_0043:  nop
29   IL_0044:  ret
30 } // end of method DerivedClass::.ctor

可以看出,则初始化DerivedClass时,DerivedClass的构造函数的IL代码顺序执行如下
1. 解析派生类实例字段的直接赋值语句,即:如果字段有直接赋值语句,则用该赋值语句或者字面量对字段进行赋值。
2. 调用基类的构造函数(逐级向上调用,知道Object的构造函数),基类的实例化过程同理。
3. 执行派生类该实例构造函数的函数体。

执行代码如下:

原文地址:https://www.cnblogs.com/myseasky/p/6709578.html