Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Заметка
Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Она включает предлагаемые изменения спецификации, а также информацию, необходимую во время проектирования и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию ECMA.
Может возникнуть некоторое несоответствие между спецификацией компонентов и завершенной реализацией. Эти различия фиксируются в соответствующем заседании по проектированию языка (LDM).
Дополнительные сведения о процессе внедрения спецификаций функций в стандарт языка C# см. в статье о спецификациях .
Проблема чемпиона: https://github.com/dotnet/csharplang/issues/2608
Сводка
Хотя платформа .NET имеет функцию , которая напрямую поддерживает написание кода инициализации для сборки (технически, модуль), она недоступна в C#. Это довольно нишевая ситуация, но как только вы сталкиваетесь с ней, решения кажутся довольно болезненными. Существуют сообщения о определенном количестве клиентов, (внутри и за пределами Майкрософт), борющихся с проблемой, и, без сомнений, существуют и другие незадокументированные случаи.
Мотивация
- Предоставьте возможность библиотекам производить предварительную единовременную инициализацию при загрузке с минимальными накладными расходами и без необходимости пользователя явно что-либо вызывать.
- Одна из проблем в текущих подходах к конструктору
staticзаключается в том, что среда выполнения должна выполнять дополнительные проверки при использовании типа со статическим конструктором, чтобы решить, нужно ли запускать статический конструктор. Это добавляет измеримые издержки. - Разрешить генераторам исходного кода выполнять логику глобальной инициализации без необходимости явного вызова каких-либо функций пользователем.
Подробный дизайн
Метод можно назначить в качестве инициализатора модуля, декорируя его атрибутом [ModuleInitializer].
using System;
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class ModuleInitializerAttribute : Attribute { }
}
Атрибут можно использовать следующим образом:
using System.Runtime.CompilerServices;
class C
{
[ModuleInitializer]
internal static void M1()
{
// ...
}
}
Некоторые требования применяются к методу, предназначенному для этого атрибута:
- Метод должен быть
static. - Метод должен быть без параметров.
- Метод должен возвращать
void. - Метод не должен быть универсальным или содержаться в универсальном типе.
- Метод должен быть доступен из содержащего модуля.
- Это означает, что эффективная доступность метода должна быть
internalилиpublic. - Это также означает, что метод не может быть локальной функцией.
- Это означает, что эффективная доступность метода должна быть
Если один или несколько допустимых методов с этим атрибутом найдены в компиляции, компилятор выдает инициализатор модуля, который вызывает каждый из методов атрибутов. Вызовы будут выдаваться в зарезервированном, но детерминированном порядке.
Недостатки
Почему мы должны не делать это?
- Возможно, существующий сторонний инструментарий для "внедрения" инициализаторов модулей является достаточным для пользователей, которые запрашивали эту функцию.
Совещания по дизайну
8 апреля 2020 г.
C# feature specifications