C# 静态构造函数的执行时机 - 只执行一次的特殊构造函数

来源:这里教程网 时间:2026-02-21 17:38:50 作者:

静态构造函数在类型第一次被使用前自动执行,且仅执行一次。它不接受访问修饰符或参数,也不能被显式调用。

什么时候触发静态构造函数?

当以下任一情况首次发生时,CLR 会确保静态构造函数已执行:

创建该类型的第一个实例(如 new MyClass() 访问该类型的任意静态字段或静态属性(读或写) 调用该类型的任意静态方法 调用该类型中定义的任意静态事件的添加/移除操作(如 MyClass.SomeEvent += handler

注意:仅引用类型名(如 typeof(MyClass) 或作为泛型参数 List)不会触发执行。

线程安全与执行保证

CLR 保证静态构造函数在整个 AppDomain(.NET Framework)或 AssemblyLoadContext(.NET Core/.NET 5+)中只执行一次,且是线程安全的。即使多个线程同时首次访问该类型,也只有一个线程执行静态构造函数,其余线程会阻塞等待其完成。

这意味着你无需手动加锁,适合用于单例初始化、全局配置加载、日志器注册等一次性设置逻辑。

执行顺序与依赖关系

如果类型有基类,静态构造函数的执行顺序是:先执行基类的静态构造函数,再执行派生类的。但要注意——这仅在基类和派生类的静态构造函数都显式定义时才生效;若基类没有静态构造函数,也不会为它“生成”一个来保证顺序。

另外,静态字段的初始化表达式(如 static int x = Compute();)会在静态构造函数体内按声明顺序插入(在构造函数代码之前),所以:

字段初始值设定项早于 static MyClass() 方法体中的代码运行 若字段初始化抛出异常,静态构造函数体不会执行

不能被继承、重载或调用

静态构造函数不是成员,不参与继承体系,子类无法重写或调用父类的静态构造函数。它属于具体类型本身,每个类型独立拥有最多一个(且不可省略访问修饰符或参数)。

试图通过反射调用(Type.GetConstructor(BindingFlags.Static...))会返回 null,因为静态构造函数在反射中被视为特殊成员,不公开暴露为常规构造器。

基本上就这些。它低调,但关键;不常写,但一旦需要,往往就是最稳妥的一次性初始化入口。

相关推荐