您可以在 IL 中的 .NET 接口上定义静态构造函数。但是,如果这样做,则在接口上运行方法时不会运行静态构造函数:
.method public static void Main() {
.entrypoint
.locals init ( class IInterface cls1 )
// InterfaceClass static constructor is run
newobj instance void InterfaceClass::.ctor()
stloc.0
ldloc.0
// IInterface static constructor is not run!!!!!
callvirt instance int32 IInterface::Method()
call void [mscorlib]System.Console::WriteLine(int32)
ret
}
.class public interface IInterface {
.method private static specialname rtspecialname void .cctor() {
ldstr "Interface static cctor"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
.method public abstract virtual instance int32 Method() {}
}
.class public InterfaceClass implements IInterface {
.method private static specialname rtspecialname void .cctor() {
ldstr "Class static cctor"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
.method public specialname rtspecialname instance void .ctor() {
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
}
.method public virtual instance int32 Method() {
ldc.i4.s 42
ret
}
}
这里发生了什么?CLR 规范 (Partition II, 10.5.3.1) 说当类型初始化器被执行时是在 Partition I 中指定的,但是我在 Partition I 中找不到任何类型初始化器执行的引用。
编辑:
我可以让接口静态初始化程序运行,但只能通过向接口添加一个静态字段,并在代码中的某处访问该字段,即使该字段实际上并未在静态构造函数中分配。因此,似乎在接口上调用方法不会使静态构造函数运行,但访问字段却可以。为什么会这样?规范中在哪里提到了这一点?