C# 实例化的执行顺序(转)
首先进行细分
1.类的成员分为:字段,属性,方法,构造函数
2.成员修饰符:静态成员,实例成员
不考虑继承的关系执行顺序为:
1.静态字段
2.静态构造方法
3.实例字段
4.实例构造方法
其中 属性和方法只有在调用的时候才执行。
下面是一段代码例子:
class Test { public static int temp; public int mNum; public int mNum2 = 2; public void Look() { Console.WriteLine("看我,我是test"); Console.WriteLine("mNum={0}", mNum); } private int mNum3 = 3; private readonly int mNum4 = 4; public int Num3 { get { return mNum3; } set { mNum3 = value; } } public Test() { temp = 1; mNum = 0; } }
定义了一个类,当我们实例化的时候
Test test = new Test();
执行过程是:
0. 静态的最先执行,仿真编译略过
1. F11 执行 public int mNum2=2; //简单的初始化字段
2. private int mNum3 = 3;
private int mNum4 = 4;
3. public Test() { temp = 1;mNum = 0; } //构造函数
注意:public int mNum;也执行了,只不过系统默认赋值0
当存在继承关系的时候,执行的顺序。
1. 子类的静态字段
2. 子类的静态构造方法
3. 子类的实例字段
4. 父类的静态字段
5. 父类的静态构造方法
6. 父类的实例字段
7. 父类的实例构造方法
8. 子类的实例构造方法
class A : Test { readonly int x = 1; public A() { PrintFields(); Look(); } readonly int c; readonly int sd = 6; public virtual void PrintFields() { Console.WriteLine("j={0},k={1}", "AA", "AA"); } } class B : A { readonly int y; int z = 2; public B() { z = -1; } public override void PrintFields() { Console.WriteLine("x={0},y={1}", "b", z); } } class C : B { int x = 1; int y = 3; public override void PrintFields() { Console.WriteLine("j={0},k={1}", "CC", y); } } static void Main(string[] args) { Console.WriteLine("======实例化Test======"); Test test = new Test(); Console.WriteLine("======实例化A======"); A a = new A(); Console.WriteLine("======实例化B======"); B b = new B(); Console.WriteLine("======实例化C======"); C c = new C(); Console.ReadKey(); }
1. 首先执行 class A中 int x = 1;,执行所有已经初始化后的字段,当执行到构造函数首执行父类字段
2. int sd = 6;
3. public A(),首先会去执行父类。
4. 0. 静态的最先执行,仿真编译略过 1. F11 执行 public int mNum2=2; //简单的初始化字段 2. private int mNum3 = 3; private int mNum4 = 4; 3. public Test() { temp = 1;mNum = 0; } //构造函数
5. public A() { PrintFields(); look(); }// 执行子类中自己的构造函数
6. public virtual void PrintFields() ;执行自己类中有意义的虚函数
7. 执行调用父类的函数 look();
8. 接下来就将要执行 class B 中的内容了。过程类似,先一步一步的执行A类,在执行Test类,实现继承。
9. 忽略部分细节,降调B类中的细节。
int z=2;
public B() 运行到这里的时候,再次执行到 public A() { PrintFields(); look(); } 的构造函数的时候,由于执行的是实例化B类,又在B类中重写了PrintFields();,实现多态。
所以执行 public override void PrintFields() { Console.WriteLine("x={0},y={1}", "b", z); } 所以此时的 z=2; 而不是 public B() { z = -1; } 中的z=-1,因为还没有执行到它,随后才执行子类中的构造函数。