静态构造函数在类型首次被使用时触发,即创建实例、访问静态成员、调用静态方法或事件增删操作时;仅引用类型名不触发。

静态构造函数在类型第一次被使用前自动执行,且仅执行一次。它不接受访问修饰符或参数,也不能被显式调用。
什么时候触发静态构造函数?
当以下任一情况首次发生时,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,因为静态构造函数在反射中被视为特殊成员,不公开暴露为常规构造器。
基本上就这些。它低调,但关键;不常写,但一旦需要,往往就是最稳妥的一次性初始化入口。






