构造函数的执行顺序

时间:2022-07-31 19:27:08

 
   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:   
   6:  namespace 实例构造器 {
   7:      /*   class A {
   8:             private static int a = 1;
   9:  
  10:             static A() {
  11:                 a = 3;
  12:             }
  13:  
  14:             public string b = "bjq";
  15:  
  16:             public A() {
  17:                 a = 2;
  18:             }
  19:  
  20:             static void Main(string[] args) {
  21:                 Console.WriteLine(a);
  22:                 Console.ReadLine();
  23:             }
  24:         */
  25:   
  26:      class Program {
  27:          public static int num1;
  28:          public static int num2 = 1;
  29:          public static int num3;
  30:          static void Main(string[] args) {
  31:              Console.WriteLine(num2);
  32:              Console.WriteLine(B.num5); //这里引用了类B的静态成员   
  33:              Console.ReadLine();
  34:          }
  35:          static Program() {
  36:              Console.WriteLine(num1);
  37:              num3 = 5; ;
  38:              Console.WriteLine(num3);
  39:          }
  40:      }
  41:   
  42:      class A {
  43:          public static int num4 = 1;
  44:          static A() //注意这里是静态的构造函数   
  45:         {
  46:              num4 = 9;
  47:          }
  48:      }
  49:   
  50:      class B {
  51:          public static int num5 = A.num4 + 1; //类B中引用了类A的静态成员   
  52:          B() { } //注意这里改为了静态的构造函数   
  53:      }
  54:  }

还有一段代码,也是说明这个使用的:

关键是静态字段以及改变顺序的this和base,注意有参数和没有参数时候的构造函数调用,基本没有问题啦

using System;
class Base {
    static Base() {
        Console.WriteLine("基类静态构造函数被调用。");
    }
 
    private static Component baseStaticField = new Component("基类静态字段被实例化。");
    private Component baseInstanceField = new Component("基类实例成员字段被实例化。");
 
    public Base() {
        Console.WriteLine("基类构造函数被调用。");
    }
}
 
//此类型用作派生类,同基类一样,它也包含静态构造函数,以及静态字段、实例成员字段各一个。
class Derived : Base {
    static Derived() {
        Console.WriteLine("派生类静态构造函数被调用。");
    }
 
    private static Component derivedStaticField = new Component("派生类静态字段被实例化。");
    private Component derivedInstanceField = new Component("派生类实例成员字段被实例化。");
 
    public Derived() {
        Console.WriteLine("派生类构造函数被调用。");
    }
}
 
//此类型用于作为Base类和Derived类的成员
//此类型在实例化的时候可以在控制台输出自定义信息,以给出相关提示
class Component {
    public Component(String info) {
        Console.WriteLine(info);
    }
}
 
//在主程序里实例化了一个子类对象
class Program {
    static void Main(string[] args) {
        Derived derivedObject = new Derived();
        Console.Read();
    }
}

总的原则,也就是根据内存的布局,CLR加载方法的过程确定的,基本知道对象的创建过程就是没有问题了~

大体的顺序:

静态字段
静态构造函数(值类型不一定执行~)
实例字段
实例构造函数(递归到System.Object逐个基类执行)使用base和this可以改变类内默认的调用顺序