如何通过反射检测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
相关产品推荐
相关产品推荐

