c# 类成员初始化顺序的特殊情况

2020-06-30 19:00:29王旭

这里直接给出C#类成员一般初始化顺序:

子类静态字段 子类静态构造 子类实例字段 父类静态字段 父类静态构造 父类实例字段 父类实例构造 子类实例构造

为什么说是“一般”初始化顺序呢?因为根据类结构的不同,类成员的初始化顺序并不是一成不变的。但是这个顺序是基础,可以推导出其他特殊的初始化顺序。下面我们就来看两种特殊的情况:

static void Main(string[] args)
{
  Console.WriteLine("---------------一般初始化顺序---------------");
  var child1 = new Child1();
  Console.WriteLine("n---------------子类静态字段初始化需要使用父类静态字段时初始化顺序---------------");
  var child2 = new Child2();
  Console.WriteLine("n---------------子类静态构造函数中使用父类静态字段时初始化顺序---------------");
  var child3 = new Child3();

  Console.ReadKey();
}

public class Child1 : Base1
{
  public static Display ChildStatic = new Display("Child static filed");

  private Display _childFiled = new Display("Child filed");

  static Child1() => Console.WriteLine("Child static ctor");

  public Child1() => Console.WriteLine("Child ctor");
}

public class Child2 : Base2
{
  /// <summary>
  /// 子类静态字段初始化需要使用父类静态字段
  /// </summary>
  public static Display ChildStatic = new Display("Child static filed", () => BaseStatic);

  private Display _childFiled = new Display("Child filed");

  static Child2() => Console.WriteLine("Child static ctor");

  public Child2() => Console.WriteLine("Child ctor");
}

public class Child3 : Base3
{
  public static Display ChildStatic = new Display("Child static filed");

  private Display _childFiled = new Display("Child filed");

  /// <summary>
  /// 子类静态构造函数中使用父类静态字段
  /// </summary>
  static Child3()
  {
    Console.WriteLine("Child static ctor");
    var baseStatic = BaseStatic;
  }

  public Child3() => Console.WriteLine("Child ctor");
}

/// <summary>
/// 3个Base类相同,这里是为了演示静态成员的初始化
/// </summary>
public class Base1
{
  public static Display BaseStatic = new Display("Base static filed");

  private Display _baseFiled = new Display("Base filed");

  static Base1() => Console.WriteLine("Base static ctor");

  public Base1() => Console.WriteLine("Base ctor");
}

public class Base2
{
  public static Display BaseStatic = new Display("Base static filed");

  private Display _baseFiled = new Display("Base filed");

  static Base2() => Console.WriteLine("Base static ctor");

  public Base2() => Console.WriteLine("Base ctor");
}

public class Base3
{
  public static Display BaseStatic = new Display("Base static filed");

  private Display _baseFiled = new Display("Base filed");

  static Base3() => Console.WriteLine("Base static ctor");

  public Base3() => Console.WriteLine("Base ctor");
}

public class Display
{
  public Display(string msg, Func<Display> displayFunc = null)
  {
    Console.WriteLine(msg);
    var display = displayFunc?.Invoke();
  }
}