You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过反射检测C#类是否存在显式静态构造函数?

如何通过反射检测C#类是否存在显式静态构造函数?

根据《ECMA标准》$14.5.6.2章节的内容,静态构造函数会影响静态字段的初始化顺序。我想要对此做强制校验,但找不到检测类型是否存在显式静态构造函数的方法——如果类包含静态字段但没有显式定义静态构造函数,C#运行时会自动生成一个。能否通过反射检测C#类是否存在显式静态构造函数?

下面的代码中,两种情况都会返回构造函数,无法直接区分是否是显式定义的:

static class NoStaticConstructor
{
    public static string Field = "x";
}

static class HasStaticConstructor
{
    static HasStaticConstructor() {}
}

public void Test()
{
    typeof(NoStaticConstructor)
        .GetConstructors(BindingFlags.Static | BindingFlags.NonPublic)
        .ShouldBeEmpty(); // 执行失败,因为运行时自动生成了静态构造函数

    typeof(HasStaticConstructor)
        .GetConstructors(BindingFlags.Static | BindingFlags.NonPublic)
        .ShouldNotBeEmpty(); // 执行成功
}

解决方案

可以通过检查静态构造函数是否带有CompilerGeneratedAttribute来区分显式定义和编译器自动生成的静态构造函数:

  • 显式编写的静态构造函数不会被标记为编译器生成
  • 由C#运行时自动生成的静态构造函数会携带该特性

修改后的校验代码如下:

using System.Runtime.CompilerServices;

public void Test()
{
    // 检测无显式静态构造函数的类
    var autoGeneratedCtor = typeof(NoStaticConstructor)
        .GetConstructors(BindingFlags.Static | BindingFlags.NonPublic)
        .FirstOrDefault();
    autoGeneratedCtor.ShouldNotBeNull();
    autoGeneratedCtor.IsDefined(typeof(CompilerGeneratedAttribute), inherit: false)
        .ShouldBeTrue(); // 验证是编译器自动生成的

    // 检测有显式静态构造函数的类
    var explicitCtor = typeof(HasStaticConstructor)
        .GetConstructors(BindingFlags.Static | BindingFlags.NonPublic)
        .FirstOrDefault();
    explicitCtor.ShouldNotBeNull();
    explicitCtor.IsDefined(typeof(CompilerGeneratedAttribute), inherit: false)
        .ShouldBeFalse(); // 验证是显式定义的
}

这个方法利用了C#编译器的特性:自动生成的成员会被标记[CompilerGenerated]特性,而开发者显式编写的成员则不会。通过反射检查该特性的存在,就能准确区分两种静态构造函数。

内容的提问来源于stack exchange,提问作者Christian Genne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 17:35:33