C#中字段、属性、静态字段的初始化顺序及对象创建默认值设置顺序
C# 字段、属性、静态成员的初始化顺序详解
咱们把这两个问题合并起来讲,本质上都是在问C#对象初始化的核心逻辑,我给你拆解得明明白白:
第一个问题:字段、属性、静态字段谁优先初始化?
优先级从高到低是:静态字段 → 实例字段 → 属性(严格来说属性本身不参与默认初始化阶段)
为啥是这个顺序?
- 静态字段属于类级别的成员,只要你的类第一次被访问(不管是创建实例还是调用静态方法/字段),它就会被最先初始化,甚至早于任何实例的诞生。
- 实例字段是对象级别的,当你创建实例时,它会在构造函数执行前完成初始化。
- 属性本质是封装访问的语法糖:手动实现的属性依赖背后的字段;自动属性(比如
public string Name { get; set; })会由编译器生成一个隐藏的实例/静态字段,这个隐藏字段会跟着对应类型初始化,但属性本身不会被主动“初始化”——只有当你通过构造函数、对象初始化器等主动赋值时,它才会修改背后的字段值。
第二个问题:创建对象实例时的初始化顺序(含默认值设置)
这里要分两种场景:
场景1:第一次访问该类(之前没创建过实例、没碰过静态成员)
初始化顺序是这样的:
- 静态成员初始化:
- 先给所有静态字段设置默认值(比如
int默认0,引用类型默认null) - 执行静态字段的显式初始化器(比如
public static int Count = 10;) - 执行静态构造函数(如果定义了的话)
- 先给所有静态字段设置默认值(比如
- 实例字段初始化:
- 给所有实例字段设置默认值
- 执行实例字段的显式初始化器(比如
public string Name = "Default";)
- 实例构造函数执行:
- 先跑基类的构造函数(如果有继承关系)
- 再执行当前类构造函数里的代码,包括给属性赋值的操作
- 属性的“初始化”:只有在构造函数、对象初始化器(比如
new MyClass { Name = "Alice" })里主动赋值时,属性才会被设置值,否则它的返回值就是背后字段的默认值。
场景2:之前已经访问过该类(比如已经创建过一个实例)
静态成员早就初始化完成了,这时候创建新实例只会从“实例字段初始化”开始执行。
给你贴个简单代码例子加深理解:
public class MyClass { // 静态字段 public static int StaticField = 10; // 实例字段 public int InstanceField = 20; // 自动属性(背后有隐藏字段) public string AutoProperty { get; set; } // 静态构造函数 static MyClass() { Console.WriteLine("静态构造函数执行"); } // 实例构造函数 public MyClass() { Console.WriteLine("实例构造函数执行"); AutoProperty = "Set in Constructor"; } } // 第一次创建实例 var obj = new MyClass(); // 输出顺序: // 静态构造函数执行 // 实例构造函数执行 // 访问StaticField得10,InstanceField得20,AutoProperty得"Set in Constructor"
内容的提问来源于stack exchange,提问作者ahmed khattab
相关产品推荐
相关产品推荐

