모듈 이니셜라이저
메모
이 문서는 기능 사양입니다. 사양은 기능의 디자인 문서 역할을 합니다. 여기에는 기능 디자인 및 개발 중에 필요한 정보와 함께 제안된 사양 변경 내용이 포함됩니다. 이러한 문서는 제안된 사양 변경이 완료되고 현재 ECMA 사양에 통합될 때까지 게시됩니다.
기능 사양과 완료된 구현 간에 약간의 불일치가 있을 수 있습니다. 이러한 차이는 관련 언어 디자인 모임 (LDM) 기록 노트에 기록됩니다.
사양문서에서 기능 세부 스펙을 C# 언어 표준에 채택되는 과정에 대해 자세히 알아볼 수 있습니다.
챔피언 이슈: https://github.com/dotnet/csharplang/issues/2608
요약
.NET 플랫폼에는 어셈블리에 대한 초기화 코드 작성(기술적으로 모듈)을 직접 지원하는 기능 있지만 C#에서는 노출되지 않습니다. 이것은 다소 틈새 시나리오이지만, 한 번 겪게 되면 해결책이 상당히 고통스러워 보입니다. 이 문제로 어려움을 겪고 있는 많은 고객(Microsoft 내부 및 외부) 보고가 있으며, 문서화되지 않은 사례는 의심의 여지가 없습니다.
동기
- 로드 시 최소한의 오버헤드와 사용자가 명시적으로 아무것도 호출할 필요 없이 라이브러리에서 즉시 일회성 초기화를 수행할 수 있도록 설정
- 현재
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
합니다. - 이는 메서드가 로컬 함수가 될 수 없음을 의미합니다.
- 즉, 메서드의 유효한 접근성은
이 특성을 가진 하나 이상의 유효한 메서드가 컴파일에서 발견되면 컴파일러는 각 특성 메서드를 호출하는 모듈 이니셜라이저를 내보낸다. 호출은 예약된 순서이지만 결정적인 순서로 전송됩니다.
단점
왜 우리는 이 작업을 하지 말아야 하나요?
- 모듈 이니셜라이저를 "삽입"하기 위한 기존 타사 도구는 이 기능을 요청한 사용자에게 충분할 수 있습니다.
디자인 회의
2020년 4월 8일
C# feature specifications