C# 类 构造函数的执行顺序
namespace Temp { class Program { static void Main(string[] args) { Class1 c = new Class1(); } } class BaseClass { int z = 3; public BaseClass() { Demo(); } public virtual void Demo() { Console.WriteLine("BaseClass.Demo"); } } class Class1 : BaseClass { int x = 1; int y; public Class1() { y = 2; } public override void Demo() { Console.WriteLine(x + y); } } }
整个过程:
- 黄色光标进入 Class1 类时跳入了第一句 int x = 1;
- 黄色光标跳过第二句 int y 指向 Class1 的构造函数;
- 在执行构造函数的代码块之前跳入了父类,黄色光标指向父类 BaseClass 的 int z = 3 语句;
- 黄色光标指向 BaseClass 的构造函数;
- 黄色光标指向构造函数内的 MethodA() 调用;
- 黄色光标跳向子类 Class1 重写的方法 MethodA();
- 查看两个字段发现 x=1, y=0;
- 黄色光标指向 Console 语句;
- 黄色光标从父类构造函数的 MethodA() 调用中跳出;
- 黄色光标从父类构造函数跳出,并再次指向子类构造函数,执行完其中的代码块;
- 直至执行完毕。
这里说明了几个顺序问题:
- 对于直接赋值的字段的赋值步骤是在构造函数之前执行,子类字段的赋值是在父类的字段赋值之前;
- 对于字段的内存分配、初始化等步骤是在我们所能看到的黄色光标进入 Class1 类的步骤之前;
- 执行构造函数前会首先执行父类的构造函数;
- 执行构造函数时 CLR 已能识别方法的覆写情况,表明方法的加载过程是在对字段的赋值步骤之前;
- int 类型的字段在分配内存、初始化阶段已默认赋了 0 值(仅限字段中的 int,方法中的int变量并非如此)。
总结:当执行 new 语句时,发生了以下几件事情(更细的情形本文暂不探讨):
- 为字段分配内存并进行初始化;
- 如果类是第一次加载(即系统中从未创建类的其它对象,或者曾经创建但因不再有引用而被 GC 全部回收),则 Copy 其实例方法至方法表;
- 为类中需要直接赋值的字段赋值;
- 执行构造函数。
PS:https://www.cnblogs.com/flaugh/archive/2010/10/12/1849018.html转载

浙公网安备 33010602011771号