Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
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 ze schůzky jazykového návrhu (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/9058
Shrnutí
partial Umožňuje modifikátoru událostí a konstruktorů oddělit části deklarace a implementace, podobně jako částečné metody a částečné vlastnosti /indexery.
partial class C
{
partial C(int x, string y);
partial event Action<int, string> MyEvent;
}
partial class C
{
partial C(int x, string y) { }
partial event Action<int, string> MyEvent
{
add { }
remove { }
}
}
Motivation
Jazyk C# již podporuje částečné metody, vlastnosti a indexery. Chybí neúplné události a konstruktory.
Částečné události by byly užitečné pro slabé knihovny událostí , kde by uživatel mohl psát definice:
partial class C
{
[WeakEvent]
partial event Action<int, string> MyEvent;
void M()
{
RaiseMyEvent(0, "a");
}
}
A generátor zdrojů poskytovaný knihovnou by poskytoval implementace:
partial class C
{
private readonly WeakEvent _myEvent;
partial event Action<int, string> MyEvent
{
add { _myEvent.Add(value); }
remove { _myEvent.Remove(value); }
}
protected void RaiseMyEvent(int x, string y)
{
_myEvent.Invoke(x, y);
}
}
Částečné události a částečné konstruktory by byly také užitečné pro generování kódu vzájemné spolupráce, jako je V Xamarinu , kde by uživatel mohl napsat částečné konstruktory a definice událostí:
partial class AVAudioCompressedBuffer : AVAudioBuffer
{
[Export("initWithFormat:packetCapacity:")]
public partial AVAudioCompressedBuffer(AVAudioFormat format, uint packetCapacity);
[Export("create:")]
public partial event EventHandler Created;
}
A generátor zdroje by vygeneroval vazby (v tomto případě s Objective-C):
partial class AVAudioCompressedBuffer : AVAudioBuffer
{
[BindingImpl(BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)]
public partial AVAudioCompressedBuffer(AVAudioFormat format, uint packetCapacity) : base(NSObjectFlag.Empty)
{
// Call Objective-C runtime:
InitializeHandle(
global::ObjCRuntime.NativeHandle_objc_msgSendSuper_NativeHandle_UInt32(
this.SuperHandle,
Selector.GetHandle("initWithFormat:packetCapacity:"),
format.GetNonNullHandle(nameof(format)),
packetCapacity),
"initWithFormat:packetCapacity:");
}
public partial event EventHandler Created
{
add { /* ... */ }
remove { /* ... */ }
}
}
Podrobný návrh
Obecné
Syntaxe deklarace události (§15.8.1) je rozšířena tak, aby umožňovala partial modifikátor:
event_declaration
- : attributes? event_modifier* 'event' type variable_declarators ';'
+ : attributes? event_modifier* 'partial'? 'event' type variable_declarators ';'
- | attributes? event_modifier* 'event' type member_name
+ | attributes? event_modifier* 'partial'? 'event' type member_name
'{' event_accessor_declarations '}'
;
Syntaxe deklarace konstruktoru instance (§15.11.1) je rozšířena tak, aby umožňovala partial modifikátor:
constructor_declaration
- : attributes? constructor_modifier* constructor_declarator constructor_body
+ : attributes? constructor_modifier* 'partial'? constructor_declarator constructor_body
;
Všimněte si, že existuje návrh , který umožňuje partial modifikátor kdekoli mezi modifikátory, nikoli pouze jako poslední (také pro metody, vlastnosti a deklarace typů).
Deklarace události s modifikátorem partial se označuje jako částečná deklarace události a je přidružená k jedné nebo více částečným událostem se zadanými názvy (všimněte si, že jedna deklarace události bez přístupových objektů může definovat více událostí).
Deklarace konstruktoru s modifikátorem partial je uvedena jako částečná deklarace konstruktoru a je přidružena k částečnému konstruktoru se zadaným podpisem.
Částečná deklarace události je uvedena jako prováděcí deklarace , pokud určuje event_accessor_declarations nebo má extern modifikátor.
V opačném případě se jedná o definující deklaraci.
Částečná deklarace konstruktoru se považuje za definující deklaraci, pokud má tělo tvořené pouze středníkem a chybí jí extern modifikátor.
Jinak se jedná o prováděcí deklaraci.
partial class C
{
// defining declarations
partial C();
partial C(int x);
partial event Action E, F;
// implementing declarations
partial C() { }
partial C(int x) { }
partial event Action E { add { } remove { } }
partial event Action F { add { } remove { } }
}
Pouze definující deklarace částečného členu se účastní vyhledávání a je zohledňována na místech, kde se používá, a pro vytvoření metadat. (S výjimkou komentářů k dokumentaci, jak je popsáno níže.) Prováděcí podpis deklarace se používá pro analýzu s možnou hodnotou null přidružených orgánů.
Částečná událost nebo konstruktor:
- Lze deklarovat pouze jako člen částečného typu.
- Musí mít jednu definici a jednu implementující deklaraci.
- Není povoleno mít
abstractmodifikátor. - Člen rozhraní nelze explicitně implementovat.
Částečná událost není polem podobná (§15.8.2), tj.
- Neobsahuje žádné záložní úložiště ani přístupové objekty generované kompilátorem.
- Dá se použít jenom v operacích
+=a-=, ne jako hodnota.
Definice částečné deklarace konstruktoru nemůže mít inicializátor konstruktoru (: this() nebo : base(); §15.11.2).
Parsovací přerušení
Povolení modifikátoru partial v dalších kontextech je zásadní změnou:
class C
{
partial F() => new partial(); // previously a method, now a constructor
@partial F() => new partial(); // workaround to keep it a method
}
class partial { }
Pro zjednodušení analyzátoru jazyka je modifikátor partial přijímán v jakékoli deklaraci typu metody (tj. místní funkce a metody skriptů nejvyšší úrovně), i když výše zmíněné změny gramatiky neuvádíme explicitně.
Atributy
Atributy výsledné události nebo konstruktoru jsou kombinované atributy částečných deklarací v odpovídajících pozicích. Kombinované atributy jsou zřetězeny v nezadaném pořadí a duplicitní položky se neodeberou.
method
Attribute_target (§22.3) se ignoruje u částečných deklarací událostí.
Atributy přístupového objektu se používají pouze z deklarací přístupových objektů (které mohou být přítomny pouze v rámci implementující deklarace).
Všimněte si, že param a returnattribute_targetjsou již ignorovány u všech deklarací událostí.
Atributy caller-info pro implementační deklaraci jsou ignorovány kompilátorem, jak je specifikováno návrhem částečných vlastností v části Caller-info atributy (všimněte si, že platí pro všechny částečné členy, které zahrnují částečné události a konstruktory).
Podpisy
Obě deklarace částečného členu musí mít odpovídající podpisy podobné částečným vlastnostem:
- Rozdíly typu a typu ref mezi částečnými deklaracemi, které jsou významné pro běhové prostředí, způsobí chybu při kompilaci.
- Rozdíly v názvech prvků n-tice mezi částečnými deklaracemi způsobí chybu v čase kompilace.
- Deklarace musí mít stejné modifikátory, i když se modifikátory mohou objevit v jiném pořadí.
- Výjimka: Toto se nevztahuje na
externmodifikátor, který se může objevit pouze v prováděcí deklaraci.
- Výjimka: Toto se nevztahuje na
- Všechny ostatní syntaktické rozdíly v podpisech částečných deklarací vedou k upozornění v době kompilace s následujícími výjimkami:
- Seznamy atributů se nemusí shodovat, jak je popsáno výše.
- Rozdíly v kontextu s možnými hodnotami null (například bez poznámek versus s poznámkami) nezpůsobí upozornění.
- Výchozí hodnoty parametrů se nemusí shodovat, ale je hlášena výstraha, pokud implementační deklarace konstruktoru obsahuje výchozí hodnoty parametrů (protože by byly ignorovány, jelikož se vyhledávání účastní pouze původní deklarace).
- K upozornění dochází v případě, že se názvy parametrů liší v definování a implementaci deklarací konstruktoru.
- Rozdíly v nulovatelnosti, které nezahrnují nevědomou nulovatelnost, vedou k upozorněním.
Komentáře k dokumentaci
Je povoleno zahrnout komentáře k dokumentu o definování i implementaci deklarace. Upozornění: Dokumentační komentáře nejsou u přístuporů událostí podporovány.
Pokud jsou komentáře k dokumentu přítomny pouze na jedné z deklarací částečného člena, tyto komentáře dokumentu se používají normálně (zobrazí se prostřednictvím rozhraní Roslyn API, vygenerované do souboru XML dokumentace).
Pokud jsou u obou deklarací částečného člena přítomny dokumentační komentáře, všechny dokumentační komentáře u definující deklarace se zahodí a použijí se pouze dokumentační komentáře u implementační deklarace.
Pokud se názvy parametrů liší mezi deklaracemi částečného členu, paramref prvky používají názvy parametrů z deklarace přidružené k komentáři dokumentace ve zdrojovém kódu.
Například paramref v komentáři k dokumentu umístěném na implementující deklaraci odkazuje na symboly parametrů implementující deklarace podle jejich názvů parametrů.
To může být matoucí, protože podpis metadat použije názvy parametrů z definující deklarace.
Doporučujeme zajistit, aby se názvy parametrů shodovaly mezi deklaracemi částečných členů, aby se zabránilo této nejasnosti.
Otevřené otázky
Druhy členů
Chceme částečné události, konstruktory, operátory, pole? Navrhujeme první dva druhy členů, ale je možné zvážit jakoukoli jinou podmnožinu.
Částečné primární konstruktory lze také zvážit, například umožnit uživateli mít stejný seznam parametrů u více deklarací částečného typu.
Umístění atributů
Měli bychom rozpoznat specifikátor cíle atributu [method:] pro částečné události (nebo pouze definování deklarací)?
Výsledné atributy přistupujícího methodobjektu by pak byly zřetězením atributů cílení z obou částí deklarace (nebo pouze definování) a atributů samoobslužného cílení a method-cílení z přístupových objektů implementační deklarace.
Kombinace atributů z různých druhů deklarací by byla nevídaná a aktuální implementace atributů odpovídajících v Roslynu to nepodporuje.
Můžeme také zvážit rozpoznávání [param:] a [return:], nejen u částečných událostí, ale také všech událostí typu pole a externích.
Další podrobnosti najdete tady: https://github.com/dotnet/roslyn/issues/77254.
C# feature specifications