Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Jegyzet
Ez a cikk egy funkcióspecifikáció. A specifikáció a funkció tervezési dokumentumaként szolgál. Tartalmazza a specifikáció javasolt módosításait, valamint a funkció tervezése és fejlesztése során szükséges információkat. Ezeket a cikkeket mindaddig közzéteszik, amíg a javasolt specifikációmódosításokat nem véglegesítik, és be nem építik a jelenlegi ECMA-specifikációba.
A szolgáltatás specifikációja és a befejezett implementáció között eltérések lehetnek. Ezeket a különbségeket a vonatkozó nyelvi tervezési értekezlet (LDM) megjegyzései rögzítik.
A funkcióspektusok C# nyelvi szabványba való bevezetésének folyamatáról a specifikációkcímű cikkben olvashat bővebben.
Bajnoki probléma: https://github.com/dotnet/csharplang/issues/2608
Összefoglalás
Bár a .NET platform rendelkezik egy funkcióval, amely közvetlenül támogatja az inicializálási kód írását a szerelvényhez (technikailag a modulhoz), ez a funkció a C#-ban nincs kitéve vagy elérhető. Ez egy meglehetősen szűk körű forgatókönyv, de miután belefut ebbe, a megoldások meglehetősen fájdalmasnak tűnnek. Vannak jelentések arról, számos ügyfél (a Microsofton belül és kívül) küzd a problémával, és kétségtelenül több nem dokumentált eset is van.
Motiváció
- Lehetővé teszi a kódtárak számára, hogy igényes, egyszeri inicializálást végezzenek betöltéskor, minimális többletterhelés mellett, és anélkül, hogy a felhasználónak explicit módon kellene meghívnia bármit
- Az aktuális
statickonstruktor-megközelítések egyik különleges fájdalompontja, hogy a futtatókörnyezetnek további ellenőrzéseket kell végeznie egy statikus konstruktort használó típus használatán annak eldöntéséhez, hogy a statikus konstruktort futtatni kell-e vagy sem. Ez mérhető többletterhelést ad hozzá. - Engedélyezze a forrásgenerátorok számára, hogy globális inicializálási logikát futtasson anélkül, hogy a felhasználónak explicit módon kellene meghívnia bármit
Részletes kialakítás
A metódusok egy [ModuleInitializer] attribútummal történő dekorálásával modul inicializálóként is kijelölhetők.
using System;
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class ModuleInitializerAttribute : Attribute { }
}
Az attribútum a következő módon használható:
using System.Runtime.CompilerServices;
class C
{
[ModuleInitializer]
internal static void M1()
{
// ...
}
}
Az attribútummal megcélzott metódusra bizonyos követelmények vonatkoznak:
- A módszernek
statickell lennie. - A metódusnak paraméter nélkülinek kell lennie.
- A metódusnak
voidkell visszaadnia. - A metódus nem lehet általános, és nem lehet egy általános típus része.
- A metódusnak elérhetőnek kell lennie a tartalmazó modulból.
- Ez azt jelenti, hogy a módszer hatékony hozzáférhetőségének
internalvagypublickell lennie. - Ez azt is jelenti, hogy a metódus nem lehet helyi függvény.
- Ez azt jelenti, hogy a módszer hatékony hozzáférhetőségének
Ha egy fordításban egy vagy több érvényes metódus található ezzel az attribútummal, a fordító egy modul inicializálót bocsát ki, amely meghívja az egyes attribútumokkal rendelkező metódusokat. A hívások fenntartott, de determinisztikus sorrendben lesznek kibocsátva.
Hátránya
Miért ne csinálni?
- Talán a "modulinicializálók befecskendezése" meglévő külső eszközkészlete elegendő azoknak a felhasználóknak, akik ezt a funkciót kérték.
Tervezési megbeszélések
2020. április 8-án
C# feature specifications