Inicializátory modulů
Poznámka
Tento článek je specifikace funkce. Specifikace slouží jako návrhový dokument pro funkci. Zahrnuje navrhované změny specifikace spolu s informacemi potřebnými při návrhu a vývoji funkce. Tyto články se publikují, dokud nebudou navrhované změny specifikace finalizovány a začleněny do aktuální specifikace ECMA.
Mezi specifikací funkce a dokončenou implementací může docházet k nějakým nesrovnalostem. Tyto rozdíly jsou zachyceny v příslušných poznámkách schůzce návrhu jazyka (LDM).
Další informace o procesu přijetí specifikací funkcí do jazyka C# najdete v článku o specifikacích .
Problém šampiona: https://github.com/dotnet/csharplang/issues/2608
Shrnutí
Ačkoli platforma .NET má vlastnost , která přímo podporuje zápis inicializačního kódu pro sestavení (technicky modul), není v jazyce C# dostupná. Jedná se o poměrně specifický scénář, a jakmile na něj narazíte, řešení se zdají být docela bolestivá. Existují zprávy o řadě zákazníků (uvnitř i mimo Microsoft), kteří se potýkají s tímto problémem, a není pochyb o dalších nezdokumentovaných případech.
Motivace
- Umožněte knihovnám provést při načítání nadšenou jednorázovou inicializaci s minimální režijní náročností a bez nutnosti, aby uživatel jakkoliv explicitně volal.
- Jedním z konkrétních problémů současných přístupů konstruktora
static
je, že modul runtime musí provádět další kontroly použití typu se statickým konstruktorem, aby rozhodl, zda je nutné spustit statický konstruktor. Tím se zvyšuje měřitelná režie. - Povolení generátorů kódu ke spuštění určité logiky globální inicializace, aniž by uživatel musel explicitně volat cokoli.
Podrobný návrh
Metodu lze označit jako inicializátor modulu pomocí atributu [ModuleInitializer]
.
using System;
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class ModuleInitializerAttribute : Attribute { }
}
Atribut lze použít takto:
using System.Runtime.CompilerServices;
class C
{
[ModuleInitializer]
internal static void M1()
{
// ...
}
}
Pro metodu, na kterou cílí tento atribut, se vztahují některé požadavky:
- Metoda musí být
static
. - Metoda musí být bez parametrů.
- Metoda musí vrátit
void
. - Metoda nesmí být obecná nebo nesmí být obsažena v obecném typu.
- Metoda musí být přístupná z obsahujícího modulu.
- To znamená, že efektivní přístupnost metody musí být
internal
nebopublic
. - To také znamená, že metoda nemůže být místní funkcí.
- To znamená, že efektivní přístupnost metody musí být
Pokud se v kompilaci nachází jedna nebo více platných metod s tímto atributem, kompilátor vygeneruje inicializátor modulu, který volá každou z atributů metod. Volání budou odesílána v předurčeném, ale deterministickém pořadí.
Nevýhody
Proč bychom to neměli?
- Možná jsou stávající nástroje od třetích stran pro "injekci" inicializátorů modulů dostatečné pro uživatele, kteří tuto funkci požadovali.
Designérské schůzky
8. dubna 2020
C# feature specifications