Delen via


Naamruimten met bestandsgelimiteerd bereik

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 Language Design Meeting (LDM) notities.

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

Probleem met kampioen: https://github.com/dotnet/csharplang/issues/137

Samenvatting

Bestandsspecifieke naamruimten gebruiken een minder uitgebreid formaat voor de gebruikelijke situatie waarin bestanden slechts één naamruimte bevatten. De indeling van de bestandsbereiknaamruimte is namespace X.Y.Z; (let op de puntkomma en het ontbreken van accolades). Dit maakt het mogelijk om bestanden zoals de volgende bestanden toe te laten:

namespace X.Y.Z;

using System;

class X
{
}

De semantiek is dat het gebruik van het formulier namespace X.Y.Z; gelijk is aan het schrijven van namespace X.Y.Z { ... } waarbij de rest van het bestand na de naamruimte met bestandsbereik zich in het ... gedeelte van een standaardnaamruimtedeclaratie bevindt.

Motivatie

Analyse van het C#-ecosysteem laat zien dat ongeveer 99,7% bestanden allemaal een van deze vormen zijn:

namespace X.Y.Z
{
    // usings

    // types
}

of

// usings

namespace X.Y.Z
{
    // types
}

Beide vormen dwingen de gebruiker echter om het merendeel van hun code in te latenspringen en een redelijk aantal ceremonies toe te voegen voor wat in feite een zeer eenvoudig concept is. Dit beïnvloedt de duidelijkheid, maakt gebruik van horizontale en verticale ruimte, en is vaak onbevredigend voor gebruikers die zowel gewend zijn aan C# als afkomstig zijn van andere talen (die hier meestal minder ceremonie hebben).

Het primaire doel van de functionaliteit is daarom om te voldoen aan de behoeften van het merendeel van het ecosysteem met minder overbodige sjablonen.

Gedetailleerd ontwerp

Dit voorstel heeft de vorm van een diff ten opzichte van de bestaande compilatie-eenheden(§14.2) van de specificatie.

Diff

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

Een compilation_unit definieert de algehele structuur van een bronbestand. Een compilatie-eenheid bestaat uit nul of meer using_directive's, gevolgd door nul of meer global_attributes's, en een compilation_unit_body. Een compilation_unit_body kan een file_scoped_namespace_declaration of nul of meer -instructie zijnen namespace_member_declarations.

compilation_unit
~~    : extern_alias_directive* using_directive* global_attributes? namespace_member_declaration*~~
    : extern_alias_directive* using_directive* global_attributes? compilation_unit_body
    ;

compilation_unit_body
    : statement* namespace_member_declaration*
    | file_scoped_namespace_declaration
    ;

... ongewijzigd...

Een file_scoped_namespace_declaration voegt leden toe die overeenkomen met de namespace_declaration waar het semantisch gelijk aan is. Zie (Naamruimtedeclaraties) voor meer informatie.

Naamruimteverklaringen

Een namespace_declaration bestaat uit het trefwoord namespace, gevolgd door een naamruimtenaam en hoofdtekst, eventueel gevolgd door een puntkomma. Een file_scoped_namespace_declaration bestaat uit het trefwoord namespace, gevolgd door een naamruimtenaam, een puntkomma en een optionele lijst met extern_alias_directives, using_directiveen type_declarations.

namespace_declaration
    : 'namespace' qualified_identifier namespace_body ';'?
    ;
    
file_scoped_namespace_declaration
    : 'namespace' qualified_identifier ';' extern_alias_directive* using_directive* type_declaration*
    ;

... unchanged ...

... ongewijzigd...

de twee bovenstaande naamruimtedeclaraties dragen bij aan dezelfde declaratieruimte, in dit geval het declareren van twee klassen met de volledig gekwalificeerde namen N1.N2.A en N1.N2.B. Omdat de twee declaraties bijdragen aan dezelfde declaratieruimte, zou het een fout zijn geweest als elk een declaratie van een lid met dezelfde naam bevatte.

Met een file_scoped_namespace_declaration kan een naamruimtedeclaratie zonder het { ... } blok worden geschreven. Bijvoorbeeld:

extern alias A;
namespace Name;
using B;
class C
{
}

is semantisch gelijk aan

extern alias A;
namespace Name
{
    using B;
    class C
    {
    }
}

In het bijzonder wordt een file_scoped_namespace_declaration hetzelfde behandeld als een namespace_declaration op dezelfde locatie in de compilation_unit met dezelfde qualified_identifier. De extern_alias_directive, using_directiveen type_declarationvan die file_scoped_namespace_declaration werken alsof ze in dezelfde volgorde in de namespace_body van die namespace_declarationzijn gedeclareerd.

Een bronbestand kan niet zowel een file_scoped_namespace_declaration als een namespace_declarationbevatten. Een bronbestand kan niet meerdere file_scoped_namespace_declarations bevatten. Een compilation_unit mag niet zowel een file_scoped_namespace_declaration als een -instructie op het hoogste niveaus bevatten. type_declarations kunnen niet voorafgaan aan een file_scoped_namespace_declaration.

Externe aliassen

... ongewijzigd...