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 で型初期化子の実行への参照が見つかりません。
編集:
インターフェイスの静的初期化子を実行することはできますが、静的フィールドをインターフェイスに追加し、コード内のどこかでそのフィールドにアクセスすることによってのみ、フィールドが静的コンストラクターで実際に割り当てられていなくてもかまいません。そのため、インターフェイスでメソッドを呼び出しても静的コンストラクターは実行されないようですが、フィールドにアクセスすると実行されます。これはなぜですか?そして、これは仕様のどこに記載されていますか?