Globální direktiva Using
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 zaznamenány v příslušných poznámkách ze schůzky 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/3428
Syntaxe direktivy using je rozšířena volitelným klíčovým slovem global
, které může předcházet klíčovému slovu using
:
compilation_unit
: extern_alias_directive* global_using_directive* using_directive* global_attributes? namespace_member_declaration*
;
global_using_directive
: global_using_alias_directive
| global_using_namespace_directive
| global_using_static_directive
;
global_using_alias_directive
: 'global' 'using' identifier '=' namespace_or_type_name ';'
;
global_using_namespace_directive
: 'global' 'using' namespace_name ';'
;
global_using_static_directive
: 'global' 'using' 'static' type_name ';'
;
- global_using_directives jsou povoleny pouze na úrovni kompilační jednotky (nelze použít uvnitř namespace_declaration).
- global_using_directives, pokud existuje, musí předcházet všem using_directives.
- Rozsah global_using_directives se vztahuje na namespace_member_declarationvšech jednotek kompilace v rámci programu. Rozsah global_using_directive konkrétně nezahrnuje jiné global_using_directives. Souběžné global_using_directives nebo ty z jiné kompilační jednotky se navzájem neovlivňují a pořadí, ve kterém jsou zapsány, je nevýznamné. Rozsah global_using_directive konkrétně nezahrnuje using_directivepřímo obsažené v žádné kompilační jednotce programu.
Účinek přidání global_using_directive do programu si můžete představit jako efekt přidání podobného using_directive, který odkazuje na stejný cílový obor názvů nebo typ ke každé kompilační jednotce programu. Cíl global_using_directive je však vyřešen v kontextu kompilační jednotky, která ji obsahuje.
§7.7 rozsahy
Jedná se o relevantní odrážkové body s navrhovanými doplňky (které jsou tučným písmem):
- Rozsah názvu definovaný extern_alias_directive se vztahuje na global_using_directives,using_directives, global_attributes a namespace_member_declarationjeho bezprostředně obsahující kompilační jednotku nebo tělo oboru názvů. extern_alias_directive nepřispívá do podkladového prostoru deklarace žádné nové členy. Jinými slovy, extern_alias_directive není tranzitivní, ale spíše ovlivňuje pouze kompilační jednotku nebo tělo oboru názvů, ve kterém se vyskytuje.
- Rozsah jména definovaného nebo importovaného global_using_directive se vztahuje na global_attributes a namespace_member_declarationvšech compilation_unitv programu.
§7.8 Názvy oborů názvů a typů
Jsou provedeny změny v algoritmu, který určuje význam namespace_or_type_name, následujícím způsobem.
Toto je relevantní bod seznamu s navrhovanými doplňky (které jsou vyznačeny tučně):
- Je-li namespace_or_type_name ve tvaru
I
nebo ve tvaruI<A1, ..., Ak>
:- Je-li
K
nula a namespace_or_type_name se zobrazí v deklaraci obecné metody (§15.6) a pokud tato deklarace obsahuje parametr typu (§15.2.3) s názvemI
, namespace_or_type_name odkazuje na tento parametr typu. - V opačném případě, pokud se namespace_or_type_name objeví v deklaraci typu, pak pro každý typ instance
T
(§15.3.2), počínaje typem instance této deklarace typu a pokračováním typem instance každé ohraničující třídy nebo struktury (pokud existuje):- Pokud je
K
nula a deklaraceT
obsahuje parametr typu s názvemI
, namespace_or_type_name odkazuje na tento parametr typu. - V opačném případě, pokud se namespace_or_type_name zobrazí v těle deklarace typu a
T
nebo některý z jeho základních typů obsahují vnořený přístupný typ s názvemI
aK
parametry typu, pak namespace_or_type_name odkazuje na tento typ vytvořený s danými argumenty typu. Pokud existuje více než jeden takový typ, je vybrán typ deklarovaný v rámci více odvozených typů. Všimněte si, že členy bez typu (konstanty, pole, metody, vlastnosti, indexery, operátory, konstruktory instancí, destruktory a statické konstruktory) a členy typu s jiným počtem parametrů typu jsou ignorovány při určování významu namespace_or_type_name.
- Pokud je
- Pokud byly předchozí kroky neúspěšné, pak pro každý obor názvů
N
, počínaje oborem názvů, ve kterém dochází k namespace_or_type_name, pokračujeme s každým uzavřením oboru názvů (pokud existuje) a končíme globálním oborem názvů, následující kroky se vyhodnotí, dokud se neskončí entita:- Pokud je
K
nula aI
je názvem oboru názvů vN
, pak:- Pokud je umístění, kde dojde k namespace_or_type_name, uzavřeno deklaraci oboru názvů pro
N
a deklarace oboru názvů obsahuje extern_alias_directive nebo using_alias_directive, které přidruží názevI
k oboru názvů nebo typu, nebo jakoukoli deklaraci oboru názvů proN
v programu obsahuje global_using_alias_directive, který přidruží názevI
k oboru názvů nebo typu, pak je namespace_or_type_name nejednoznačný a dojde k chybě v době kompilace. - V opačném případě namespace_or_type_name odkazuje na obor názvů pojmenovaný
I
vN
.
- Pokud je umístění, kde dojde k namespace_or_type_name, uzavřeno deklaraci oboru názvů pro
- Pokud
N
obsahuje přístupný typ s názvemI
a parametry typuK
, pak:- Pokud je
K
nula a umístění, kde dojde k namespace_or_type_name, je uzavřena deklarace oboru názvů proN
a deklarace oboru názvů obsahuje extern_alias_directive nebo using_alias_directive, které přidruží názevI
k oboru názvů nebo typu, nebo jakoukoli deklaraci oboru názvů proN
v programu obsahuje global_using_alias_directive, který přidruží názevI
obor názvů nebo typ, pak namespace_or_type_name je nejednoznačný a dojde k chybě kompilace. - V opačném případě namespace_or_type_name odkazuje na typ vytvořený s danými argumenty typu.
- Pokud je
- V opačném případě, pokud se místo, kde se nachází namespace_or_type_name, nachází v rámci deklarace oboru názvů pro
N
:- Pokud je
K
nula a deklarace oboru názvů obsahuje extern_alias_directive nebo using_alias_directive, která přidruží názevI
k importovanému oboru názvů nebo typu, nebo deklarace oboru názvů proN
v programu obsahuje global_using_alias_directive, který přidruží názevI
k importovanému oboru názvů nebo typu. pak namespace_or_type_name odkazuje na tento obor názvů nebo typ. - V opačném případě, pokud obory názvů a deklarace typů importované prostřednictvím using_namespace_directivea using_alias_directivekonkrétní deklarace oboru názvů a obory názvů a deklarace typů importované prostřednictvím global_using_namespace_directivea global_using_static_directivejakékoli deklarace oboru názvů pro
N
v programu obsahují přesně jeden přístupný typ s názvemI
a typovými parametryK
, pak namespace_or_type_name odkazuje na tento typ vytvořený s uvedenými argumenty typu. - V opačném případě, pokud obory názvů a deklarace typů importované using_namespace_directives a using_alias_directivedeklarace oboru názvů a obory názvů a deklarace typů importované global_using_namespace_directives a global_using_static_directivedeklarací oboru názvů pro
N
v programu obsahují více než jeden přístupný typ s názvemI
aK
parametry typu, namespace_or_type_name je nejednoznačný a dojde k chybě.
- Pokud je
- Pokud je
- V opačném případě je namespace_or_type_name nedefinovaný a dojde k chybě v době kompilace.
- Je-li
Jednoduché názvy §12.8.4
Změny v pravidlech vyhodnocení simple_name se provádějí následujícím způsobem.
Toto je relevantní odrážka s navrhovanými doplňky (které jsou tučným písmem):
- Jinak platí, že pro každý obor názvů
N
, počínaje oborem názvů, ve kterém se vyskytuje simple_name, pokračujeme s každým vnějším oborem názvů (pokud existuje) a končícím globálním oborem názvů, následující kroky se vyhodnocují, dokud se nenalezne entita:- Pokud je
K
nula aI
je název oboru jmen vN
, pak:- Pokud je umístění, kde dojde k simple_name, obklopena deklarací oboru názvů pro
N
a deklarace oboru názvů proN
obsahuje extern_alias_directive nebo using_alias_directive, které přidružují názevI
k oboru názvů nebo typu, nebo jakákoli deklarace oboru názvů proN
v programu obsahuje global_using_alias_directive, která přidružuje názevI
k oboru názvů nebo typu, pak je simple_name nejednoznačný a dojde k chybě v době kompilace. - V opačném případě simple_name odkazuje na obor názvů pojmenovaný
I
vN
.
- Pokud je umístění, kde dojde k simple_name, obklopena deklarací oboru názvů pro
- Pokud
N
obsahuje přístupný typ s názvemI
a parametry typuK
, pak:- Pokud je
K
nula a umístění, kde dojde k simple_name, je uzavřena deklarace oboru názvů proN
a deklarace oboru názvů obsahuje extern_alias_directive nebo using_alias_directive, které přidruží názevI
k oboru názvů nebo typu, nebo jakoukoli deklaraci oboru názvů proN
v programu obsahuje global_using_alias_directive, který přidruží názevI
k oboru názvů. nebo zadejte, pak je simple_name nejednoznačný a dojde k chybě v době kompilace. - V opačném případě namespace_or_type_name odkazuje na typ vytvořený s danými argumenty typu.
- Pokud je
- V opačném případě, když je umístění, kde se nachází simple_name, uzavřeno deklarací oboru názvů pro
N
:- Pokud je
K
nula a deklarace oboru názvů obsahuje extern_alias_directive nebo using_alias_directive, která přidruží názevI
k importovanému oboru názvů nebo typu, nebo deklarace oboru názvů proN
v programu obsahuje global_using_alias_directive, který přidruží názevI
k importovanému oboru názvů nebo typu. pak simple_name odkazuje na tento obor názvů nebo typ. - V opačném případě, pokud obory názvů a deklarace typů importované using_namespace_directives a using_static_directivedeklarace oboru názvů a obory názvů a deklarace typů importované global_using_namespace_directives a global_using_static_directivevšech deklarací oboru názvů pro
N
v programu, obsahují přesně jeden přístupný typ nebo statického člena bez přípony s názvemI
aK
parametry typu, simple_name odkazuje na tento typ nebo člen vytvořený s danými argumenty typu. - V opačném případě, pokud obory názvů a typy importované podle using_namespace_directiveve vyhlášení oboru názvů a obory názvů a deklarace typů importované podle global_using_namespace_directivea global_using_static_directivev jakékoli deklaraci oboru názvů pro
N
v programu obsahují více než jeden přístupný typ nebo statického člena, který není rozšiřovací metodou, se jménemI
aK
parametry typu, je simple_name nejednoznačné a dojde k chybě.
- Pokud je
- Pokud je
Vyvolání rozšiřující metody §12.8.10.3
V algoritmu jsou provedeny změny, které hledají nejlepší type_nameC
následujícím způsobem.
Toto je relevantní odrážka s navrhovanými doplněními (které jsou vyznačeny tučně ()):
- Počínaje nejbližší uzavřenou deklarací oboru názvů, pokračuje se s každou další uzavřenou deklarací oboru názvů a končí obsahující kompilační jednotkou, přičemž se postupně hledá kandidátská sada rozšiřujících metod:
- Pokud daná jednotka oboru názvů nebo kompilační jednotka přímo obsahuje ne generické deklarace typu
Ci
s způsobilými rozšiřujícími metodamiMj
, pak sada těchto rozšiřujících metod je kandidátskou sadou. - Pokud typy
Ci
importované pomocí using_static_declarations a přímo deklarované v oborech názvů importovaných pomocí using_namespace_directivev daném oboru názvů nebo kompilační jednotce , a pokud je dosaženo kompilační jednotky, jsou importovány pomocí global_using_static_declarations a přímo deklarovány v oborech názvů importovaných pomocí global_using_namespace_directivev programu, přímo obsahují způsobilé rozšiřující metodyMj
, pak je sada těchto rozšiřujících metod kandidátskou sadou.
- Pokud daná jednotka oboru názvů nebo kompilační jednotka přímo obsahuje ne generické deklarace typu
Kompilační jednotky §14.2
compilation_unit definuje celkovou strukturu zdrojového souboru. Kompilační jednotka se skládá z nula nebo více global_using_directivenásledovaných nula nebo více using_directivenásledovaných nulou nebo více global_attributes následovanými nulou nebo více namespace_member_declarations.
compilation_unit
: extern_alias_directive* global_using_directive* using_directive* global_attributes? namespace_member_declaration*
;
Program jazyka C# se skládá z jedné nebo více jednotek kompilace, z nichž každý je obsažený v samostatném zdrojovém souboru. Při kompilaci programu jazyka C# se všechny kompilační jednotky zpracovávají společně. Kompilační jednotky tedy mohou záviset na sobě navzájem, možná cyklickým způsobem.
global_using_directivejednotek kompilace ovlivňují global_attributes a namespace_member_declarationvšech jednotek kompilace v programu.
Externí aliasy §14.4
Rozsah extern_alias_directive se vztahuje na global_using_directives,using_directives, global_attributes a namespace_member_declarationv rámci kompilační jednotky nebo těla oboru názvů, které ho bezprostředně obsahují.
Použití direktiv aliasů §14.5.2
Pořadí, ve kterém jsou using_alias_directivezapsány, nemá žádný význam a rozlišení namespace_or_type_name odkazovaného using_alias_directive není ovlivněno using_alias_directive samotným nebo jinými using_directivev bezprostředně obsahující kompilační jednotce nebo těle oboru názvů, a, pokud using_alias_directive je okamžitě obsažen v kompilační jednotce, není ovlivněna global_using_directivev programu. Jinými slovy, namespace_or_type_nameusing_alias_directive se vyřeší, jako by kompilační jednotka nebo tělo oboru názvů, ve kterém se bezprostředně nachází, nemělo žádné using_directivea pokud je using_alias_directive bezprostředně obsaženo v kompilační jednotce, program nemá žádné global_using_directives. using_alias_directive však mohou být ovlivněny extern_alias_directivev bezprostředně obsahující kompilační jednotce nebo těle oboru názvů.
Globální direktivy aliasů using
global_using_alias_directive zavádí identifikátor, který slouží jako alias pro obor názvů nebo typ v rámci programu.
global_using_alias_directive
: 'global' 'using' identifier '=' namespace_or_type_name ';'
;
V rámci deklarací členů v libovolné kompilační jednotce programu, který obsahuje global_using_alias_directive, lze identifikátor zavedený global_using_alias_directive použít k odkazování na daný obor názvů nebo typ.
Identifikátor direktivy global_using_alias musí být jedinečný v rámci prostoru deklarace libovolné kompilační jednotky programu, který obsahuje direktivu global_using_alias .
Stejně jako běžné členy jsou názvy zavedené global_using_alias_directives skryté podobnými pojmenovanými členy v vnořených oborech.
Pořadí, ve kterém jsou global_using_alias_directivezapsány, nemá žádný význam a řešení namespace_or_type_name referencovaného pomocí global_using_alias_directive není ovlivněno global_using_alias_directive samotným ani jinými global_using_directivenebo using_directivev programu. Jinými slovy, namespace_or_type_nameglobal_using_alias_directive se vyřeší, jako by přímo obsahující kompilační jednotka neměla žádné using_directivea celý program neměl žádné global_using_directive. global_using_alias_directive však může být ovlivněn extern_alias_directives v bezprostředně obsahující kompilační jednotce.
global_using_alias_directive může vytvořit alias pro libovolný obor názvů nebo typ.
Přístup k oboru názvů nebo typu prostřednictvím aliasu poskytuje přesně stejný výsledek jako přístup k danému oboru názvů nebo typu prostřednictvím deklarovaného názvu.
Použití aliasů může pojmenovat uzavřený vytvořený typ, ale nemůže pojmenovat nevázanou deklaraci obecného typu bez zadání argumentů typu.
Globální použití direktiv oboru názvů
global_using_namespace_directive přináší typy obsažené ve jmenném prostoru do programu, což umožňuje použití identifikátoru každého typu bez kvalifikace.
global_using_namespace_directive
: 'global' 'using' namespace_name ';'
;
V rámci deklarací členů v programu, který obsahuje global_using_namespace_directive, lze odkazovat přímo na typy obsažené v daném oboru názvů.
global_using_namespace_directive importuje typy obsažené v daném oboru názvů, ale konkrétně neimportuje vnořené obory názvů.
Na rozdíl od global_using_alias_directivemůže global_using_namespace_directive importovat typy, jejichž identifikátory jsou již definovány v kompilační jednotce programu. V dané jednotce kompilace jsou názvy importované jakýmkoli global_using_namespace_directive v programu skryty členy se stejnými názvy v této jednotce kompilace.
Pokud více než jeden obor názvů nebo typ importovaný global_using_namespace_directives nebo global_using_static_directiveve stejném programu obsahuje typy se stejným názvem, odkazy na tento název jako type_name jsou považovány za nejednoznačné.
Dále, když více než jeden obor názvů nebo typ importovaný pomocí global_using_namespace_directivenebo global_using_static_directiveve stejném programu obsahuje typy nebo členy se stejným názvem, jsou odkazy na tento název jako simple_name považovány za nejednoznačné.
namespace_name, na které se odkazuje global_using_namespace_directive, se řeší stejným způsobem jako namespace_or_type_name, na které se odkazuje global_using_alias_directive. Proto global_using_namespace_directiveve stejném programu navzájem neovlivňují a mohou být zapsány v libovolném pořadí.
Globální použití statických direktiv
global_using_static_directive importuje vnořené typy a statické členy obsažené přímo v deklaraci typu do obsahujícího programu, čímž se umožňuje použít identifikátor každého takového člena a typu bez kvalifikace.
global_using_static_directive
: 'global' 'using' 'static' type_name ';'
;
V rámci deklarací členů v programu, který obsahuje global_using_static_directive, přístupné vnořené typy a statické členy (s výjimkou rozšiřujících metod) obsažené přímo v deklaraci daného typu lze odkazovat přímo.
Konkrétně global_using_static_directive neimportuje rozšiřující metody přímo jako statické metody, ale zpřístupňuje je pro vyvolání metody rozšíření.
global_using_static_directive importuje pouze členy a typy deklarované přímo v daném typu, nikoli členy a typy deklarované v základních třídách.
Nejednoznačnosti mezi více global_using_namespace_directives a global_using_static_directives jsou popsány v sekci pro global_using_namespace_directives výše.
Kvalifikovaný člen aliasu §14.8
Jsou provedeny změny v algoritmu určujícím význam qualified_alias_member následujícím způsobem.
Toto je relevantní odrážka s navrhovanými doplňky (které jsou tučným písmem):
Jinak počínaje deklarací oboru názvů (§14.3), který bezprostředně obsahuje qualified_alias_member (pokud existuje), pokračováním s každou obklopující deklarací oboru názvů (pokud existuje) a končící jednotkou kompilace obsahující qualified_alias_member, tyto kroky se vyhodnocují, dokud není nalezena entita:
- Pokud deklarace oboru názvů nebo jednotka kompilace obsahuje using_alias_directive, který přidruží
N
k typu, nebo, když je dosažena kompilační jednotka, program obsahuje global_using_alias_directive, který přidružíN
k typu, pak qualified_alias_member není definována a dojde k chybě v době kompilace. - Jinak pokud deklarace oboru názvů nebo kompilační jednotka obsahuje extern_alias_directive nebo using_alias_directive, které přidruží
N
k oboru názvů, *nebo pokud je dosažena kompilační jednotka, program obsahuje global_using_alias_directive, který přidružíN
k oboru názvů, pak:- Pokud obor názvů přidružený k
N
obsahuje obor názvů s názvemI
aK
je nula, qualified_alias_member odkazuje na tento obor názvů. - Jinak pokud obor názvů přidružený k
N
obsahuje ne generický typ s názvemI
aK
je nula, qualified_alias_member odkazuje na tento typ. - Jinak pokud obor názvů přidružený k
N
obsahuje typ pojmenovanýI
, který má parametry typuK
, pak qualified_alias_member odkazuje na tento typ vytvořený s danými argumenty typu. - V opačném případě je qualified_alias_member nedefinovaný a dojde k chybě v době kompilace.
- Pokud obor názvů přidružený k
- Pokud deklarace oboru názvů nebo jednotka kompilace obsahuje using_alias_directive, který přidruží
C# feature specifications