Как оказалось, есть, но не всеми языками этой семейки поддерживается. Этот пост является переводом короткой (но содержательной) статьи по этой теме.
В CLR версий 1.0 и 1.1. Поддерживаются инициализаторы типов. Многие с ними знакомы, но на всякий случай предоставлю выжимку из ECMA-335: CLR Раздел 2 Метаданные и формат файла:
Тип (класс, интерфейс, тип значения) может иметь специальный метод называемый инициализатором типа, который используется чтобы инициализировать сам тип (при этом, вызывается при первом обращении к этому типу, а не во время загрузки самой сборки — прим. перев.). Метод должен быть статическим, иметь 0 параметров и не иметь возвращаемого типа, должен быть помечен как rtspecialname и specialname, и должен называться .cctor.
Подобно конструкторам экземпляра, инициализаторы типа могут писать в статические поля других типов с атрибутом initonly.
.class public EngineeringData extends [mscorlib]System.Object { .field private static initonly float64[] coefficient .method private specialname rtspecialname static void .cctor() cil managed { .maxstack 1 // allocate array of 4 Double ldc.i4.4 newarr [mscorlib]System.Double // point initonly field to new array stsfld float64[] EngineeringData::coefficient // code to initialize array elements goes here ret } }
CLR версии 2.0 в свою очередь предоставляет инициализаторы модуей. Аналогичны инициализаторам типа, с тем лишь отличием что инициализатор модуля ассоциируется с модулем, а не типом. Т.к. он не ассоциирован с типом, он является глобальной функцией.
Описание инициализатора модуля:
Модуль может содержать специальный метод, называемый инициализатором модуля в целях самостоятельной инициализации модуля.
Все модули могут иметь инициализатор. Метод должен быть статичным, членом модуля, принимать 0 параметров, не иметь возвращаемого типа, быть помеченным как rtspecialname и specialname, и иметь имя .cctor.
Никаких ограничений на код этих методов не накладывается. Инициализаторам модуля разрешается выполнять как управляемый, так и неуправляемый код.
Инициализация модуля гарантирует:
- Инициализатор модуля исполняется во время, или через некоторое время до первого обращения к типам, методам или данным, определённым в модуле. Наличие самого инициализатора в модуле необязательно.
- Инициализатор модуля вызывается единожды для каждого модуля, за исключением явного вызова инициализатора кодом пользователя.
- Ни один из методов, вызванных явно или не-явно из инициализатора модуля, не сможет получить доступ к данным, методам или типам, объявленным в модуле, до окончания выполнения кода инициализатора модуля.
Т.к. C# не имеет глобальных функций, создание инициализаторов модуля в нём недоступно.
Как описано в чате MSDN VC++, C++/CLI внутренне использует инициализаторы модулей. (C++/CLI internally uses module initializer, as described in the MSDN VC++ chat script.)
Следующий код является декомпилом в ildasm модуля msvcm80.dll:
.method assembly specialname rtspecialname static void .cctor() cil managed { .custom instance void [mscorlib]System.Diagnostics.DebuggerStepThroughAttribute::.ctor() = ( 01 00 00 00 ) // Code size 39 (0x27) .maxstack 2 .locals ([0] valuetype '<CrtImplementationDetails>'.LanguageSupport languageSupport) IL_0000: ldloca.s languageSupport IL_0002: call valuetype '<CrtImplementationDetails>'.LanguageSupport* modopt([mscorlib]System.Runtime.CompilerServices.CallConvThiscall) '<CrtImplementationDetails>.LanguageSupport.{ctor}'(valuetype '<CrtImplementationDetails>'.LanguageSupport* modopt([mscorlib]System.Runtime.CompilerServices.IsConst) modopt([mscorlib]System.Runtime.CompilerServices.IsConst)) IL_0007: pop .try { IL_0008: ldloca.s languageSupport IL_000a: call void modopt([mscorlib]System.Runtime.CompilerServices.CallConvThiscall) '<CrtImplementationDetails>.LanguageSupport.Initialize'(valuetype '<CrtImplementationDetails>'.LanguageSupport* modopt([mscorlib]System.Runtime.CompilerServices.IsConst) modopt([mscorlib]System.Runtime.CompilerServices.IsConst)) IL_000f: leave.s IL_001f } // end .try fault { IL_0011: ldftn void modopt([mscorlib]System.Runtime.CompilerServices.CallConvThiscall) '<CrtImplementationDetails>.LanguageSupport.{dtor}'(valuetype '<CrtImplementationDetails>'.LanguageSupport* modopt([mscorlib]System.Runtime.CompilerServices.IsConst) modopt([mscorlib]System.Runtime.CompilerServices.IsConst)) IL_0017: ldloca.s languageSupport IL_0019: call void ___CxxCallUnwindDtor(method void *(void*), void*) IL_001e: endfinally } // end handler IL_001f: ldloca.s languageSupport IL_0021: call void modopt([mscorlib]System.Runtime.CompilerServices.CallConvThiscall) 'gcroot<System::String ^>.{dtor}'(valuetype 'gcroot<System::String ^>'* modopt([mscorlib]System.Runtime.CompilerServices.IsConst) modopt([mscorlib]System.Runtime.CompilerServices.IsConst)) IL_0026: ret } // end of method 'Global Functions'::.cctor
ссылка на оригинал статьи http://habrahabr.ru/post/175185/
Добавить комментарий