Вы можете определить статический конструктор в интерфейсе .NET в IL. Однако, если вы это сделаете, статический конструктор не будет запущен при запуске метода в интерфейсе:
.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 (Раздел II, 10.5.3.1) указано, что выполнение инициализаторов типов указано в Разделе I, но я не могу найти в Разделе I никаких ссылок на выполнение инициализатора типов.
РЕДАКТИРОВАТЬ:
I может запустить статический инициализатор интерфейса, но только путем добавления статического поля к интерфейсу и доступа к этому полю где-нибудь в коде, даже если поле фактически не назначено в статическом конструкторе. Таким образом, кажется, что вызов метода в интерфейсе не запускает статический конструктор, а доступ к полю делает. Почему это так? И где это упоминается в спецификации?