Delen via


Globale gebruiksrichtlijn

Notitie

Dit artikel is een functiespecificatie. De specificatie fungeert als het ontwerpdocument voor de functie. Het bevat voorgestelde specificatiewijzigingen, samen met informatie die nodig is tijdens het ontwerp en de ontwikkeling van de functie. Deze artikelen worden gepubliceerd totdat de voorgestelde specificaties zijn voltooid en opgenomen in de huidige ECMA-specificatie.

Er kunnen enkele verschillen zijn tussen de functiespecificatie en de voltooide implementatie. Deze verschillen worden vastgelegd in de relevante LDM-notities (Language Design Meeting) .

Meer informatie over het proces voor het aannemen van functiespeclets in de C#-taalstandaard vindt u in het artikel over de specificaties.

Kampioenprobleem: https://github.com/dotnet/csharplang/issues/3428

Syntaxis voor een using-instructie wordt uitgebreid met een optioneel global trefwoord dat het using trefwoord kan voorafgaan.

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 ';'
    ;
  • De global_using_directivezijn alleen toegestaan op compilatie-eenheidsniveau (kan niet worden gebruikt binnen een namespace_declaration).
  • De global_using_directives, indien aanwezig, moeten voorafgaan aan using_directives.
  • Het bereik van een global_using_directives strekt zich uit over de namespace_member_declarations van alle compilatie-eenheden binnen het programma. Het bereik van een global_using_directive omvat specifiek geen andere global_using_directives. Peer-global_using_directives of die uit een andere compilatie-eenheid hebben dus geen invloed op elkaar en de volgorde waarin ze worden geschreven, is onbelangrijk. Het bereik van een global_using_directive omvat specifiek geen using_directivedie direct zijn opgenomen in een compilatie-eenheid van het programma.

Het effect van het toevoegen van een global_using_directive aan een programma kan worden beschouwd als het effect van het toevoegen van een vergelijkbare using_directive die wordt omgezet in dezelfde doelnaamruimte of type aan elke compilatie-eenheid van het programma. Het doel van een global_using_directive wordt echter opgelost in de context van de compilatie-eenheid die deze bevat.

§7.7 Reikwijdten

Dit zijn de relevante bulletpoints met voorgestelde toevoegingen (die in vetgedrukt zijn):

  • Het bereik van de naam die door een extern_alias_directive is gedefinieerd, strekt zich uit over de global_using_directives,using_directives, global_attributes en namespace_member_declarations van de bijbehorende compilatie-eenheid of naamruimte-inhoud. Een extern_alias_directive draagt geen nieuwe leden bij aan de onderliggende declaratieruimte. Met andere woorden, een extern_alias_directive is niet transitief, maar is alleen van invloed op de hoofdtekst van de compilatie-eenheid of naamruimte waarin deze zich voordoet.
  • Het bereik van een naam die is gedefinieerd of geïmporteerd door een global_using_directive breidt zich uit over de global_attributes en namespace_member_declarationvan alle compilation_units in het programma.

§7.8 naamruimte en typ namen

Wijzigingen worden aangebracht in het algoritme dat de betekenis van een namespace_or_type_name als volgt bepaalt.

Dit is het relevante opsommingsteken met voorgestelde toevoegingen (vetgedrukt):

  • Als de namespace_or_type_name van de vorm I is of van de vorm I<A1, ..., Ak>:
    • Als K nul is en de namespace_or_type_name wordt weergegeven in een algemene methodedeclaratie (§15.6) en als die declaratie een typeparameter bevat (§15.2.3) met de naam I, verwijst de namespace_or_type_name naar die typeparameter.
    • Als de namespace_or_type_name anders binnen een typeverklaring verschijnt, wordt voor elk exemplaartype T (§15.3.2), beginnend met het exemplaartype van die typeverklaring en verder te gaan met het exemplaartype van elke omvattende klasse- of structverklaring (indien van toepassing):
      • Als K nul is en de declaratie van T een typeparameter met de naam Ibevat, verwijst de namespace_or_type_name naar die typeparameter.
      • Als de namespace_or_type_name binnen de typedeclaratie verschijnt en T of een van zijn basistypen een genest toegankelijk type met de naam I en K typeparameters bevat, verwijst de namespace_or_type_name naar dat type dat met de gegeven typeargumenten is samengesteld. Als er meer dan één dergelijk type is, wordt het type geselecteerd dat binnen het meer afgeleide type is gedeclareerd. Houd er rekening mee dat niet-typeleden (constanten, velden, methoden, eigenschappen, indexeerfuncties, operators, instantieconstructors, destructors en statische constructors) en typeleden met een ander aantal typeparameters worden genegeerd bij het bepalen van de betekenis van de namespace_or_type_name.
    • Als de vorige stappen niet kunnen worden uitgevoerd, worden voor elke naamruimte N, te beginnen met de naamruimte waarin de namespace_or_type_name plaatsvindt, door te gaan met elke omsluitende naamruimte (indien van toepassing) en eindigend met de globale naamruimte, de volgende stappen worden geëvalueerd totdat een entiteit zich bevindt:
      • Als K nul is en I de naam van een naamruimte in Nis, dan:
        • Als de locatie waar de namespace_or_type_name plaatsvindt, wordt ingesloten door een naamruimtedeclaratie voor N en de naamruimtedeclaratie een extern_alias_directive of using_alias_directive bevat die de naam I koppelt aan een naamruimte of type, of een naamruimtedeclaratie voor N in het programma een global_using_alias_directive bevat die de naam I koppelt aan een naamruimte of type, dan is de namespace_or_type_name dubbelzinnig en treedt er een compilatiefout op.
        • Anders verwijst de namespace_or_type_name naar de naamruimte met de naam I in N.
      • Anders, als N een toegankelijk type is met de naam I en K typeparameters, dan:
        • Als K nul is en de locatie waar de namespace_or_type_name plaatsvindt, wordt ingesloten door een naamruimtedeclaratie voor N en bevat de naamruimtedeclaratie een extern_alias_directive of using_alias_directive die de naam I koppelt aan een naamruimte of type, of een naamruimtedeclaratie voor N in het programma een global_using_alias_directive bevat die de naam I koppelt aan een naamruimte of type, vervolgens de namespace_or_type_name dubbelzinnig is en er treedt een compilatiefout op.
        • Anders verwijst de namespace_or_type_name naar het type dat is samengesteld met de opgegeven typeargumenten.
      • Anders, als de locatie waar de namespace_or_type_name voorkomt, ingesloten is door een naamruimtedeclaratie voor N:
        • Als K nul is en de naamruimtedeclaratie een extern_alias_directive of using_alias_directive bevat die de naam I koppelt aan een geïmporteerde naamruimte of -type, bevat of een naamruimtedeclaratie voor N in het programma een global_using_alias_directive die de naam I koppelt aan een geïmporteerde naamruimte of -type, verwijst de namespace_or_type_name naar die naamruimte of het type.
        • Als de naamruimten en typedeclaraties die zijn geïmporteerd door de using_namespace_directive's en using_alias_directive's van de naamruimtedeclaratie en de naamruimten en typedeclaraties die zijn geïmporteerd door de global_using_namespace_directive's en global_using_static_directive's van een naamruimtedeclaratie voor N in het programma exact één toegankelijk type bevatten met de naam I en K typeparameters, dan verwijst de namespace_or_type_name naar dat type, samengesteld met de opgegeven typeargumenten.
        • Als de naamruimten en typedeclaraties die zijn geïmporteerd door de using_namespace_directives en using_alias_directives van een naamruimteverklaring en de naamruimten en typedeclaraties die zijn geïmporteerd door de global_using_namespace_directives en global_using_static_directives van een willekeurige naamruimtedeclaratie voor N in het programma meer dan één toegankelijk type met naam I en K typeparameters bevatten, dan is de namespace_or_type_name niet eenduidig en treedt er een fout op.
    • Anders is de namespace_or_type_name niet gedefinieerd en treedt er een compilatiefout op.

Eenvoudige namen §12.8.4

Wijzigingen worden als volgt aangebracht in de simple_name evaluatieregels.

Dit is het relevante opsommingsteken met voorgestelde toevoegingen (vetgedrukt):

  • Anders worden voor elke naamruimte N, beginnend met de naamruimte waarin de simple_name voorkomt, verdergaand met elke omsluitende naamruimte (indien van toepassing) en waarbij wordt geëindigd met de globale naamruimte, de volgende stappen geëvalueerd totdat een entiteit is gelokaliseerd.
    • Als K nul is en I de naam van een naamruimte in Nis, dan:
      • Als de locatie waar de simple_name plaatsvindt, wordt ingesloten door een naamruimtedeclaratie voor N en de naamruimtedeclaratie een extern_alias_directive of using_alias_directive bevat die de naam I koppelt aan een naamruimte of type, of een naamruimtedeclaratie voor N in het programma een global_using_alias_directive bevat die de naam I koppelt aan een naamruimte of type, dan is de simple_name dubbelzinnig en treedt er een compilatietijdfout op.
      • Anders verwijst de simple_name naar de naamruimte met de naam I in N.
    • Anders, als N een toegankelijk type is met de naam I en K typeparameters, dan:
      • Als K nul is en de locatie waar de simple_name plaatsvindt, wordt ingesloten door een naamruimtedeclaratie voor N en de naamruimtedeclaratie een extern_alias_directive of using_alias_directive bevat die de naam I koppelt aan een naamruimte of type, of wanneer een naamruimtedeclaratie voor N in het programma een global_using_alias_directive bevat die de naam I koppelt aan een naamruimte of type, dan is de simple_name ambigu en ontstaat er een compilatiefout.
      • Anders verwijst de namespace_or_type_name naar het type dat is samengesteld met de opgegeven typeargumenten.
    • Als de locatie waar de simple_name voorkomt, wordt omsloten door een naamruimtedeclaratie voor N:
      • Als K nul is en de naamruimtedeclaratie een extern_alias_directive of using_alias_directive bevat die de naam I koppelt aan een geïmporteerde naamruimte of -type, bevat of een naamruimtedeclaratie voor N in het programma een global_using_alias_directive die de naam I koppelt aan een geïmporteerde naamruimte of -type, verwijst de simple_name naar die naamruimte of het type.
      • Indien de naamruimten en typedeclaraties die zijn geïmporteerd door de using_namespace_directive's en using_static_directive's van de naamruimtedeclaratie en de naamruimten en typedeclaraties die zijn geïmporteerd door de global_using_namespace_directive's en global_using_static_directive's van een naamruimtedeclaratie voor N in het programma exact één toegankelijk type of niet-uitbreidings statisch lid bevatten met naam I en K typeparameters, dan verwijst de simple_name naar dat type of lid dat is geconstrueerd met de gegeven typeargumenten.
      • Als de naamruimten en typen die zijn geïmporteerd door de using_namespace_directives van de naamruimtedeclaratie en de naamruimten en typedeclaraties die zijn geïmporteerd door de global_using_namespace_directives en de global_using_static_directives van een naamruimtedeclaratie voor N in het programma meer dan één toegankelijk type of een statisch lid van een niet-extensiemethode bevatten met de naam I en de typeparameters K, dan is de simple_name dubbelzinnig en treedt er een fout op.

Uitbreidingsmethode aanroepen §12.8.10.3

Wijzigingen worden aangebracht in het algoritme om de beste type_nameC als volgt te vinden. Dit is het relevante opsommingsteken met voorgestelde toevoegingen (vetgedrukt):

  • Beginnend met de dichtstbijzijnde naamruimtedeclaratie, doorgaand met elke declaratie van de naamruimte en eindigend met de bijbehorende compilatie-eenheid, worden opeenvolgende pogingen gedaan om een kandidaatset met extensiemethoden te vinden:
    • Als de opgegeven naamruimte of compilatie-eenheid rechtstreeks niet-algemene typedeclaraties bevat Ci met in aanmerking komende uitbreidingsmethoden Mj, is de set van deze uitbreidingsmethoden de kandidaatset.
    • Als typen Ci zijn geïmporteerd door using_static_declarations en rechtstreeks zijn gedeclareerd in naamruimten die zijn geïmporteerd door using_namespace_directivein de opgegeven naamruimte of compilatie-eenheid , en als de bereikbare compilatie-eenheid is geïmporteerd door global_using_static_declarations en rechtstreeks gedeclareerd in naamruimten die door global_using_namespace_directivein het programma zijn geïmporteerd, en rechtstreeks in aanmerking komende uitbreidingsmethoden Mjbevatten, dan is de set van deze uitbreidingsmethoden de kandidaatset.

Compilatie-eenheden §14.2

Een compilation_unit definieert de algehele structuur van een bronbestand. Een compilatie-eenheid bestaat uit nul of meer global_using_directivegevolgd door nul of meer using_directivegevolgd door nul of meer global_attributes gevolgd door nul of meer namespace_member_declarations.

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

Een C#-programma bestaat uit een of meer compilatie-eenheden, elk in een afzonderlijk bronbestand. Wanneer een C#-programma wordt gecompileerd, worden alle compilatie-eenheden samen verwerkt. Compilatie-eenheden kunnen dus afhankelijk zijn van elkaar, mogelijk op circulaire wijze.

De global_using_directivevan een compilatie-eenheid zijn van invloed op de global_attributes en namespace_member_declarationvan alle compilatie-eenheden in het programma.

Externe aliassen §14.4

Het bereik van een extern_alias_directive strekt zich uit over de global_using_directives,using_directives, global_attributes en namespace_member_declarations van zijn direct omringende compilatie-eenheid of naamruimte.

Gebruik van aliasrichtlijnen §14.5.2

De volgorde waarin using_alias_directives zijn geschreven, heeft geen significantie en de oplossing van de namespace_or_type_name waarnaar wordt verwezen door een using_alias_directive wordt niet beïnvloed door de using_alias_directive zelf of door andere using_directives in de direct bevattende compilatieeenheid of naamruimtetekst, en, als de using_alias_directive onmiddellijk is opgenomen in een compilatie-eenheid, niet wordt beïnvloed door de global_using_directives in het programma. Met andere woorden, de namespace_or_type_name van een using_alias_directive wordt opgelost alsof de onmiddellijk omvattende compilatie-eenheid of naamruimte-lichaam geen using_directives had, en als de using_alias_directive direct is opgenomen in een compilatie-eenheid, het programma geen global_using_directiveshad. Een using_alias_directive kan echter worden beïnvloed door extern_alias_directives in de direct omvattende compilatie-eenheid of naamruimte.

Globale instructies voor het gebruik van aliassen

Een global_using_alias_directive introduceert een identifier die dient als een alias voor een naamruimte of type binnen het programma.

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

Binnen ledenverklaringen in een compilatie-eenheid van een programma dat een global_using_alias_directivebevat, kan de identifier die door de global_using_alias_directive wordt geïntroduceerd, worden gebruikt om te verwijzen naar de opgegeven naamruimte of het type.

De identificatie van een global_using_alias_directive moet uniek zijn binnen de declaratieruimte van elke compilatie-eenheid in een programma dat de global_using_alias_directivebevat.

Net als gewone leden worden namen die door global_using_alias_directives worden geïntroduceerd, verborgen door leden met vergelijkbare namen in geneste scopes.

De volgorde waarin global_using_alias_directives zijn geschreven, heeft geen betekenis en de resolutie van de namespace_or_type_name waarnaar wordt verwezen door een global_using_alias_directive wordt niet beïnvloed door de global_using_alias_directive zelf of door andere global_using_directives of using_directives in het programma. Met andere woorden: de namespace_or_type_name van een global_using_alias_directive wordt opgelost alsof de direct bevattende compilatie-eenheid geen using_directives had en het gehele bevattende programma geen global_using_directives had. Een global_using_alias_directive kan echter worden beïnvloed door extern_alias_directive's in de onmiddellijk omvattende compilatie-eenheid.

Een global_using_alias_directive kan een alias maken voor elke naamruimte of elk type.

Het benaderen van een naamruimte of type via een alias levert precies hetzelfde resultaat op als het benaderen van die naamruimte of type via de gedeclareerde naam.

Het gebruik van aliassen kan een gesloten geconstrueerd type een naam geven, maar kan geen niet-gebonden generieke typedeclaratie zonder typeargumenten benoemen.

Globale instructies voor het gebruik van naamruimten

Een global_using_namespace_directive importeert de typen die zich in een namespace bevinden in het programma, zodat de identificator van elk type zonder kwalificatie kan worden gebruikt.

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

Binnen liddeclaraties in een programma dat een global_using_namespace_directivebevat, kunnen de typen in de opgegeven naamruimte rechtstreeks worden verwezen.

Een global_using_namespace_directive importeert de typen in de opgegeven naamruimte, maar importeert geen geneste naamruimten.

In tegenstelling tot een global_using_alias_directivekan een global_using_namespace_directive typen importeren waarvan de id's al zijn gedefinieerd in een compilatie-eenheid van het programma. In feite worden in een bepaalde compilatie-eenheid de namen die door een global_using_namespace_directive in het programma worden geïmporteerd, verborgen door leden met een vergelijkbare naam in de compilatie-eenheid.

Wanneer meer dan één naamruimte of type dat is geïmporteerd door global_using_namespace_directives of global_using_static_directivein hetzelfde programma typen met dezelfde naam bevat, worden verwijzingen naar die naam als een type_name beschouwd als dubbelzinnig.

Wanneer meer dan één naamruimte of type dat wordt geïmporteerd door global_using_namespace_directives of global_using_static_directives in hetzelfde programma, typen of leden met dezelfde naam bevat, worden verwijzingen naar die naam als een simple_name als dubbelzinnig beschouwd.

De namespace_name waarnaar wordt verwezen door een global_using_namespace_directive wordt op dezelfde manier opgelost als de namespace_or_type_name waarnaar wordt verwezen door een global_using_alias_directive. Dus global_using_namespace_directives in hetzelfde programma hebben geen invloed op elkaar en kunnen in elke volgorde worden geschreven.

Globale statische richtlijnen gebruiken

Een global_using_static_directive importeert de geneste typen en statische leden die rechtstreeks zijn opgenomen in een typedeclaratie in het omringende programma, waardoor de identificator van elk lid en type zonder kwalificatie kan worden gebruikt.

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

Binnen liddeclaraties in een programma dat een global_using_static_directivebevat, kunnen de toegankelijke geneste typen en statische leden (behalve uitbreidingsmethoden) binnen de declaratie van het opgegeven type rechtstreeks worden verwezen.

Een global_using_static_directive importeert extensiemethoden niet rechtstreeks als statische methoden, maar maakt ze beschikbaar voor het aanroepen van extensiemethoden.

Een global_using_static_directive importeert alleen leden en typen die rechtstreeks in het opgegeven type zijn gedeclareerd, niet leden en typen die zijn gedeclareerd in basisklassen.

Dubbelzinnigheden tussen meerdere global_using_namespace_directives en global_using_static_directives worden besproken in de sectie voor global_using_namespace_directives (hierboven).

Gekwalificeerd aliaslid §14.8

Wijzigingen worden aangebracht in het algoritme dat de betekenis van een qualified_alias_member als volgt bepaalt.

Dit is het relevante opsommingsteken met voorgestelde toevoegingen (vetgedrukt):

  • Anders worden, vanaf de declaratie van de naamruimte (§14.3) onmiddellijk met de qualified_alias_member (indien aanwezig) met elke naamruimtedeclaratie (indien aanwezig) en eindigend met de compilatie-eenheid met de qualified_alias_member, de volgende stappen geëvalueerd totdat een entiteit zich bevindt:

    • Als de naamruimtedeclaratie of compilatie-eenheid een using_alias_directive bevat die N koppelt aan een type, of, wanneer een compilatie-eenheid is bereikt, bevat het programma een global_using_alias_directive die N koppelt aan een type, de qualified_alias_member niet gedefinieerd is en er een compilatiefout optreedt.
    • Als de naamruimtedeclaratie of compilatie-eenheid een extern_alias_directive of using_alias_directive bevat die N koppelt aan een naamruimte, *of, wanneer een compilatie-eenheid wordt bereikt, bevat het programma een global_using_alias_directive die N koppelt aan een naamruimte,:
      • Als de naamruimte die is gekoppeld aan N een naamruimte bevat met de naam I en K nul is, verwijst de qualified_alias_member naar die naamruimte.
      • Als de naamruimte die is gekoppeld aan N een niet-algemeen type bevat met de naam I en K nul is, verwijst de qualified_alias_member naar dat type.
      • Als de naamruimte die aan N is gekoppeld een type genaamd I bevat met K typeparameters, verwijst het -qualified_alias_member naar dat type, geconstrueerd met de gegeven typeargumenten.
      • Anders is de qualified_alias_member niet gedefinieerd en treedt er een compilatiefout op.