• 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. 执行派生类该实例构造函数的函数体。

    执行代码如下:

  • 相关阅读:
    String方法
    多态
    观察者模式
    ArrayList和LinkList
    唐岛湾
    AForge.Net C#的操作视频,照片读写功能
    JqGrid填坑
    日常点滴
    日常点滴
    EF Core 填坑记录
  • 原文地址:https://www.cnblogs.com/myseasky/p/6709578.html
Copyright © 2020-2023  润新知