Megosztás a következőn keresztül:


Globális használatról szóló irányelv

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/3428

A használatirányelv szintaxisa egy választható global kulcsszóval bővül, amely megelőzheti a using kulcsszót:

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 ';'
    ;
  • A global_using_directivecsak a fordítási egység szintjén engedélyezett (namespace_declarationbelül nem használható).
  • A global_using_directive-nek, ha van ilyen, minden using_directiveelőtt kell lennie.
  • Egy global_using_directivehatóköre a program összes fordítási egységének namespace_member_declarations-ére terjed ki. A global_using_directive hatóköre nem tartalmaz más global_using_directive-kat. Így a társ global_using_directivevagy azok, amelyek egy másik fordítási egységből származnak, nem befolyásolják egymást, és az, hogy milyen sorrendben vannak írva, jelentéktelen. A global_using_directive hatóköre kifejezetten nem tartalmazza a program bármely összeállítási egységében közvetlenül szereplő using_directive-t.

Egy global_using_directive programhoz való hozzáadásának hatása hasonló ahhoz, mintha minden fordítási egységhez hozzáadnánk egy hasonló using_directive direktívát, amely ugyanahhoz a célnévtérhez vagy típushoz oldódik fel. A global_using_directive célpontja azonban az azt tartalmazó fordítási egység kontextusában oldódik fel.

§7.7 hatókörök

Ezek a javasolt kiegészítésekkel rendelkező listajelek (amelyek félkövér ):

  • A extern_alias_directive által definiált név hatóköre a fordítási egységet vagy névtértörzset tartalmazó global_using_directive,using_directives, global_attributes és namespace_member_declarations-jére terjed ki. Az extern_alias_directive nem ad hozzá új tagokat az alapjául szolgáló deklarációs térhez. Más szóval egy extern_alias_directive nem tranzitív, hanem csak a fordítási egységre vagy névtértörzsre van hatással, amelyben ez történik.
  • Egy global_using_directive által definiált vagy importált név hatóköre kiterjed a program összes compilation_unitglobal_attributes és namespace_member_declarations-ére.

§7.8 Névtér és típusnevek

A namespace_or_type_name jelentését meghatározó algoritmus az alábbiak szerint módosul.

Ez a megfelelő listajel a javasolt kiegészítésekkel (amelyek félkövér ):

  • Ha a namespace_or_type_nameI vagy I<A1, ..., Ak>alakú:
    • Ha K nulla, és a namespace_or_type_name egy általános metódusdeklarációban (15.6. §) belül jelenik meg, és ha a deklaráció tartalmaz egy típusparamétert (§15.2.3) a név I, akkor a namespace_or_type_name erre a típusparaméterre hivatkozik.
    • Ellenkező esetben, ha a namespace_or_type_name egy típusdeklarációban jelenik meg, akkor minden példánytípus esetében T (15.3.2. §) az adott típusdeklaráció példánytípusától kezdve és az egyes belefoglaló osztályok vagy szerkezetdeklarációk példánytípusával folytatva (ha vannak ilyenek):
      • Ha K nulla, és a T deklarációja tartalmaz egy Inevű típusparamétert, akkor a namespace_or_type_name erre a típusparaméterre hivatkozik.
      • Ellenkező esetben, ha a namespace_or_type_name a típusdeklaráció törzsében jelenik meg, és T vagy bármely alaptípusa tartalmaz egy beágyazott akadálymentes típust, amelynek neve I és K típusparaméterek, akkor a namespace_or_type_name az adott típusargumentumokkal létrehozott típusra hivatkozik. Ha több ilyen típus is létezik, a származtatott típuson belül deklarált típus lesz kiválasztva. Vegye figyelembe, hogy a nem típustagokat (állandókat, mezőket, metódusokat, tulajdonságokat, indexelőket, operátorokat, példánykonstruktorokat, destruktorokat és statikus konstruktorokat) és más típusú paraméterekkel rendelkező típustagokat a rendszer figyelmen kívül hagyja a namespace_or_type_namejelentésének meghatározásakor.
    • Ha az előző lépések sikertelenek voltak, akkor az egyes névterek Nesetén – kezdve azzal a névtérrel, amelyben a namespace_or_type_name megjelenik, folytatva az egyes beágyazó névterekkel (ha vannak), és befejezve a globális névtérrel – a következő lépések kerülnek kiértékelésre, amíg egy entitást meg nem találunk.
      • Ha K nulla, és I névtér neve N-ben, akkor:
        • Ha a namespace_or_type_name helyét egy N névtér-deklarációja tartalmazza, és a névtér-deklaráció tartalmaz egy extern_alias_directive vagy using_alias_directive, amely a nevet I egy névtérhez vagy típushoz társítja, vagy a program N névtér-deklarációja tartalmaz egy global_using_alias_directive, amely a névteret vagy típust társítja a I névtérhez vagy típushoz, akkor a namespace_or_type_name nem egyértelmű, és fordítási időhiba lép fel.
        • Ellenkező esetben a namespace_or_type_name a IN nevű névtérre hivatkozik.
      • Ellenkező esetben, ha N olyan akadálymentes típust tartalmaz, amelynek neve I és K típusparaméterek, akkor:
        • Ha K nulla, és a namespace_or_type_name helyét egy névtér-deklaráció tartalmazza N, és a névtér-deklaráció tartalmaz egy extern_alias_directive vagy using_alias_directive, amely a nevet I névtérhez vagy típushoz társítja, vagy a program N névtér-deklarációja tartalmaz egy global_using_alias_directive, amely társítja a I nevét névtér vagy típus, akkor a namespace_or_type_name nem egyértelmű, és fordítási időhiba lép fel.
        • Ellenkező esetben a namespace_or_type_name az adott típusargumentumokkal létrehozott típusra hivatkozik.
      • Ellenkező esetben, ha a namespace_or_type_name előfordulása egy Nnévtér deklaráció által van körülvéve:
        • Ha K nulla, és a névtér-deklaráció tartalmaz egy extern_alias_directive vagy using_alias_directive, amely a névteret I egy importált névtérhez vagy típushoz társítja, vagy a program N névtér-deklarációja tartalmaz egy global_using_alias_directive, amely a nevet I egy importált névtérhez vagy típushoz társítja, akkor a namespace_or_type_name erre a névtérre vagy típusra hivatkozik.
        • Ellenkező esetben, ha a névtér deklaráció using_namespace_directiveés using_alias_directiveáltal importált névterek és típusdeklarációk, valamint a program bármelyik névtér deklarációjához tartozó Nés global_using_static_directiveáltal importált névterek és típusdeklarációk pontosan egy olyan elérhető típust tartalmaznak, amely rendelkezik névvel I és K típusparaméterekkel, akkor a namespace_or_type_name az adott típusargumentumokkal létrehozott típusra hivatkozik.
        • Ellenkező esetben, ha a using_namespace_directives és using_alias_directives által importált névterek és típusdeklarációk a névtérdeklaráció N bármely névtérdeklarációjában több mint egy elérhető típust tartalmaznak, amelyeknek I a neve és K a típusparaméterei vannak, akkor a namespace_or_type_name nem egyértelmű, és hiba lép fel.
    • Ellenkező esetben a namespace_or_type_name nincs definiálva, és fordítási időhiba lép fel.

Egyszerű nevek §12.8.4

A simple_name értékelési szabályok az alábbiak szerint módosulnak.

Ez a megfelelő listajel a javasolt kiegészítésekkel (amelyek félkövér ):

  • Ellenkező esetben minden névtér N, kezdve azzal a névtérrel, amelyben a simple_name bekövetkezik, az egyes beágyazó névtérekkel folytatva (ha van ilyen), és a globális névtérrel végződik, a rendszer a következő lépéseket értékeli ki, amíg egy entitás nem található:
    • Ha K nulla, és I névtér neve N-ben, akkor:
      • Ha a simple_name helyét egy N névtér-deklarációja tartalmazza, és a névtér-deklaráció tartalmaz egy extern_alias_directive vagy using_alias_directive, amely a nevet I egy névtérhez vagy típushoz társítja, vagy a program N névtér-deklarációja tartalmaz egy global_using_alias_directive, amely a névteret vagy típust társítja a névtérhez I, akkor a simple_name nem egyértelmű, és fordítási időhiba lép fel.
      • Ellenkező esetben a simple_name a IN nevű névtérre hivatkozik.
    • Ellenkező esetben, ha N olyan akadálymentes típust tartalmaz, amelynek neve I és K típusparaméterek, akkor:
      • Ha K nulla, és a simple_name helyét egy névtér deklarációja tartalmazza N, és a névtér-deklaráció tartalmaz egy extern_alias_directive vagy using_alias_directive, amely a nevet I egy névtérhez vagy típushoz társítja, vagy a program N névtér-deklarációja tartalmaz egy global_using_alias_directive, amely a névteret I társítja egy névtérhez vagy írja be, akkor a simple_name nem egyértelmű, és fordítási időhiba lép fel.
      • Ellenkező esetben a namespace_or_type_name az adott típusargumentumokkal létrehozott típusra hivatkozik.
    • Ellenkező esetben, ha a simple_name előfordulásának helyét egy Nnévtér deklaráció körülzárja:
      • Ha K nulla, és a névtér-deklaráció tartalmaz egy extern_alias_directive vagy using_alias_directive, amely a névteret I egy importált névtérhez vagy típushoz társítja, vagy a program N névtér-deklarációja tartalmaz egy global_using_alias_directive, amely a nevet I egy importált névtérhez vagy típushoz társítja, ezután a simple_name erre a névtérre vagy típusra hivatkozik.
      • Ellenkező esetben, ha a névtér-deklarálási using_namespace_directiveés using_static_directives által importált névterek és típusdeklarációk, valamint a program névtér-deklarációinak Nés global_using_static_directives által importált névterek és típusdeklarációk pontosan egy olyan akadálymentes típust vagy nem kiterjesztésű statikus tagot tartalmaznak, amelynek neve I és K típusparaméterek, akkor a simple_name az adott típusargumentumokkal létrehozott típusra vagy tagra hivatkozik.
      • Ellenkező esetben, ha a using_namespace_directive-k által importált névterek és típusok a névtérdeklaráció N program bármely névtérdeklarációjából importált névterek és típusdeklarációk több mint egy hozzáférhető típust vagy nem bővítménymetódusú statikus tagot tartalmaznak, amelyeknek a neve I és K típusparaméterek vannak, akkor a simple_name nem egyértelmű és hiba történik.

Bővítménymetódus-meghívások §12.8.10.3

Az algoritmuson változtatások történtek annak érdekében, hogy megtaláljuk a legjobb type_nameC-t az alábbiak szerint. Ez a megfelelő listajel a javasolt kiegészítésekkel (amelyek félkövér ):

  • A legközelebbi bezárt névter deklarációtól kezdve, továbbhaladva az egyes beágyazó névtér-deklarációkkal, és az azt tartalmazó fordítási egységgel végződve, egymást követő próbálkozások történnek a kiterjesztési metódusok jelölt készletének megkeresésére:
    • Ha a megadott névtér vagy fordítási egység közvetlenül nem generikus típusú deklarációkat tartalmaz, Ci alkalmazható kiterjesztési metódusokkal Mj, akkor ezeknek a kiterjesztési metódusoknak a halmaza a jelölt halmaz.
    • Ha a Ci által importált és using_namespace_directiveáltal az adott névtérben vagy fordítási egységben importált névterekben típusok , és ha a fordítási egységet elérik, global_using_static_declarations importálják és közvetlenül deklarálják a program global_using_namespace_directiveáltal importált névterekben, közvetlenül tartalmazzák a jogosult bővítménymetszeti módszereket Mj, akkor a bővítménymetelyek halmaza a jelöltkészlet.

Összeállítási egységek §14.2

A compilation_unit egy forrásfájl általános szerkezetét határozza meg. A fordítási egység nullából vagy több global_using_directives-ből áll, amelyet nulla vagy több using_directivekövet, majd nulla vagy több global_attributes, majd nulla vagy több namespace_member_declarations.

compilation_unit
    : extern_alias_directive* global_using_directive* using_directive* global_attributes? namespace_member_declaration*
    ;

A C#-programok egy vagy több fordítási egységből állnak, amelyek mindegyike külön forrásfájlban található. Egy C#-program fordításakor az összes fordítási egység együtt lesz feldolgozva. Így a fordítási egységek egymástól függhetnek, esetleg körkörös módon.

A program fordítási egységeinek global_using_directive-ja befolyásolja az összes fordítási egység global_attributes és namespace_member_declaration-jait.

Extern aliasok §14.4

Az extern_alias_directive hatóköre kiterjed a közvetlenül tartalmazó fordítási egység vagy névtér törzsben lévő global_using_directive,using_directive, global_attributes és namespace_member_declarationelemekre.

Alias irányelvek használata §14.5.2

Az using_alias_directiveírási sorrendjének nincs jelentősége, és az using_alias_directive által hivatkozott namespace_or_type_name felbontását nem befolyásolja maga a using_alias_directive vagy más using_directivea fordítási egység vagy névtér törzsét közvetlenül tartalmazó szövegtörzsben, , és ha a using_alias_directive azonnal tartalmazza egy fordítási egység, nem érinti a global_using_directives a program. Más szóval, a using_alias_directivenamespace_or_type_name úgy van feloldva, mintha az azt azonnal tartalmazó fordítási egység vagy névtértörzsben nem lenne using_directive, és ha a using_alias_directive közvetlenül egy fordítási egységben van, akkor a program nem tartalmazna global_using_directive-ket. A using_alias_directive-t azonban befolyásolhatják az extern_alias_directive-ak a közvetlenül tartalmazó fordítási egységben vagy névtér törzsben.

Globális alias-direktívák használata

A global_using_alias_directive olyan azonosítót vezet be, amely aliasként szolgál egy névtérhez vagy típushoz a programban.

global_using_alias_directive
    : 'global' 'using' identifier '=' namespace_or_type_name ';'
    ;

A global_using_alias_directivetartalmazó programok bármely összeállítási egységében található tagdeklarációkban a global_using_alias_directive által bevezetett azonosító használható a megadott névtérre vagy típusra való hivatkozáshoz.

Egy global_using_alias_directiveazonosítójának egyedinek kell lennie a global_using_alias_directivetartalmazó program bármely fordítási egységének deklarációs területén belül.

A normál tagokhoz hasonlóan az global_using_alias_directiveáltal bevezetett neveket is elrejtik a hasonló nevű tagok a beágyazott hatókörökben.

Az global_using_alias_directiveírási sorrendjének nincs jelentősége, és a global_using_alias_directive által hivatkozott namespace_or_type_name értelmezését nem befolyásolja a global_using_alias_directive vagy a program egyéb global_using_directivevagy using_directivesem. Más szóval a global_using_alias_directivenamespace_or_type_name úgy oldódik fel, mintha a közvetlenül tartalmazó összeállítási egységnek nem lenne using_directive-e, és az egész programnak nem lenne global_using_directive-e. A global_using_alias_directive azonban érintheti extern_alias_directive-ket az azonnal tartalmazó fordítási egységben.

A global_using_alias_directive bármilyen névtérhez vagy típushoz létrehozhat aliast.

A névtér vagy a típus aliason keresztüli elérése pontosan ugyanazt az eredményt eredményezi, mint az adott névtér elérése vagy a deklarált név alapján történő beírás.

Az aliasok használatával zárt, konstruktált típust nevezhet el, de nem nevezhet el kötetlen általános típusdeklarációt típusargumentumok megadása nélkül.

Globális névtér-direktívák

Egy global_using_namespace_directive a névtérben található típusokat importálja a programba, így az egyes típusok azonosítója minősítés nélkül használható.

global_using_namespace_directive
    : 'global' 'using' namespace_name ';'
    ;

A global_using_namespace_directivetartalmazó program tagdeklarációiban a megadott névtérben található típusok közvetlenül hivatkozhatók.

Egy global_using_namespace_directive importálja a megadott névtérben található típusokat, de nem importál beágyazott névtereket.

A global_using_alias_directiveellentétben a global_using_namespace_directive olyan típusokat importálhatnak, amelyek azonosítói már definiálva vannak a program fordítási egységében. Valójában egy adott fordítási egységben a program bármely global_using_namespace_directive által importált neveket a fordítási egység hasonló nevű tagjai elrejtik.

Ha ugyanazon program global_using_namespace_directives vagy global_using_static_directiveáltal importált több névtér vagy típus azonos néven tartalmaz típusokat, akkor az adott névre type_name való hivatkozások nem egyértelműnek minősülnek.

Továbbá, ha egy programban többször is importálják a global_using_namespace_directives vagy a global_using_static_directives struktúrát, és ezek típusokat vagy tagokat tartalmaznak azonos névvel, akkor az ilyen nevek simple_name formában való hivatkozása kétértelműnek tekintendő.

A global_using_namespace_directive által hivatkozott namespace_name ugyanúgy van feloldva, mint a global_using_alias_directiveáltal hivatkozott namespace_or_type_name. A global_using_namespace_directivedirektívák ugyanabban a programban nem befolyásolják egymást, és bármilyen sorrendben írhatók.

Statikus irányelvek globális használata

A global_using_static_directive közvetlenül a típusdeklarációban szereplő beágyazott típusokat és statikus tagokat importálja a kódoló programba, így az egyes tagok és típusok azonosítóját minősítés nélkül lehet használni.

global_using_static_directive
    : 'global' 'using' 'static' type_name ';'
    ;

A global_using_static_directivetartalmazó program tagdeklarációiban az adott típus deklarációjában közvetlenül található beágyazott típusokra és statikus tagokra (a bővítménymetódusok kivételével) közvetlenül lehet hivatkozni.

A global_using_static_directive nem importálja közvetlenül statikus metódusként a bővítménymetódusokat, hanem elérhetővé teszi őket a bővítménymetódus-meghíváshoz.

A global_using_static_directive csak az adott típusban közvetlenül deklarált tagokat és típusokat importálja, az alaposztályokban deklarált tagokat és típusokat nem.

A több global_using_namespace_directiveés global_using_static_directives közötti kétértelműségeket a global_using_namespace_directive(fenti) szakasz ismerteti.

Minősített aliastag §14.8

Az algoritmust az alábbiak szerint módosítják, amely meghatározza a qualified_alias_member jelentését.

Ez a megfelelő listajel a javasolt kiegészítésekkel (amelyek félkövér ):

  • Ellenkező esetben a qualified_alias_member (ha van) közvetlenül tartalmazó névtérdeklarációval (14.3) kezdve az egyes magában foglaló névtérdeklarációval (ha van ilyen) folytatva, és a qualified_alias_membertartalmazó összeállítási egységgel végződik, a rendszer az alábbi lépéseket értékeli ki, amíg egy entitás nem található:

    • Ha a névtér-deklaráció vagy fordítási egység olyan using_alias_directive tartalmaz, amely N társít egy típushoz, vagy fordítási egység elérésekor a program tartalmaz egy global_using_alias_directive, amely N társít egy típushoz, akkor a qualified_alias_member nincs definiálva, és fordítási időhiba lép fel.
    • Ellenkező esetben, ha a névtér-deklaráció vagy fordítási egység olyan extern_alias_directive vagy using_alias_directive tartalmaz, amely N társít egy névtérhez, *vagy fordítási egység elérésekor a program tartalmaz egy global_using_alias_directive, amely N társít egy névtérhez, ezután:
      • Ha a N társított névtér egy I nevű névteret tartalmaz, és K nulla, akkor a qualified_alias_member erre a névtérre hivatkozik.
      • Ellenkező esetben, ha a N társított névtér egy nem általános típusú, I nevű típust tartalmaz, és K nulla, akkor a qualified_alias_member erre a típusra hivatkozik.
      • Ellenkező esetben, ha a N társított névtér tartalmaz egy I nevű típust, amely K típusparaméterekkel rendelkezik, akkor a qualified_alias_member az adott típusargumentumokkal létrehozott típusra hivatkozik.
      • Ellenkező esetben a qualified_alias_member nincs definiálva, és fordítási időhiba lép fel.