了解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. 执行派生类该实例构造函数的函数体。
执行代码如下: