Dateibereichsnamespaces
Anmerkung
Dieser Artikel ist eine Featurespezifikation. Die Spezifikation dient als Designdokument für das Feature. Es enthält vorgeschlagene Spezifikationsänderungen sowie Informationen, die während des Entwurfs und der Entwicklung des Features erforderlich sind. Diese Artikel werden veröffentlicht, bis die vorgeschlagenen Spezifikationsänderungen abgeschlossen und in die aktuelle ECMA-Spezifikation aufgenommen werden.
Es kann einige Abweichungen zwischen der Featurespezifikation und der abgeschlossenen Implementierung geben. Diese Unterschiede sind in den einschlägigen Notizen zum Sprachdesign-Meeting (LDM).
Weitere Informationen über den Prozess zur Aufnahme von Feature Speclets in den C#-Sprachstandard finden Sie in dem Artikel über die specifications.
Zusammenfassung
Datei-spezifische Namespaces verwenden ein weniger ausführliches Format für den typischen Fall, dass Dateien nur einen Namespace enthalten. Das Format des dateiabhängigen Namespace ist namespace X.Y.Z;
(beachten Sie das Semikolon und das Fehlen der geschweiften Klammern). Dies ermöglicht Dateien wie die folgenden:
namespace X.Y.Z;
using System;
class X
{
}
Die Semantik besagt, dass die Verwendung der namespace X.Y.Z;
Form ist gleichbedeutend mit dem Schreiben namespace X.Y.Z { ... }
wobei der Rest der Datei, der auf den dateispezifischen Namensraum folgt, im ...
Abschnitt einer Standard-Namespace-Deklaration.
Motivation
Eine Analyse des C#-Ökosystems zeigt, dass etwa 99,7 % der Dateien eine dieser beiden Formen aufweisen
namespace X.Y.Z
{
// usings
// types
}
oder
// usings
namespace X.Y.Z
{
// types
}
Beide Formen zwingen den Benutzer jedoch, den größten Teil seines Codes einzurücken und fügen eine ganze Menge Zeremonien für ein eigentlich sehr einfaches Konzept hinzu. Dies beeinträchtigt die Übersichtlichkeit, verbraucht horizontalen und vertikalen Platz und ist oft unbefriedigend für Benutzer, die sowohl an C# gewöhnt sind als auch aus anderen Sprachen kommen (die hier in der Regel weniger Zeremonien haben).
Das Hauptziel der Funktion ist es daher, die Bedürfnisse der Mehrheit des Ökosystems mit weniger unnötigem Ballast zu erfüllen.
Detailliertes Design
Dieser Vorschlag hat die Form eines Diffs zu den bestehenden Kompilationseinheiten (§14.2) Abschnitt der Spezifikation.
Diff
A Kompilier-Einheit definiert die Gesamtstruktur einer Quelldatei. Eine Kompilationseinheit besteht aus null oder mehr using_directives gefolgt von null oder mehr globale_Attribute gefolgt von null oder mehr namespace_member_declarations.
A Kompilier-Einheit definiert die Gesamtstruktur einer Quelldatei. Eine Kompilationseinheit besteht aus null oder mehr using_directives gefolgt von null oder mehr globale_Attribute gefolgt von einer kompilierung_einheit_body. A kompilierung_einheit_body kann entweder ein file_scoped_namespace_declaration oder null oder mehr Anweisungs und 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
;
... unverändert...
A file_scoped_namespace_declaration wird Mitglieder beisteuern, die den namespace_declaration ist semantisch äquivalent zu. Siehe (Namespace-Deklarationen) für weitere Einzelheiten.
Namespacedeklarationen
A namespace_declaration besteht aus dem Schlüsselwort namespace
, gefolgt von einem Namespace-Namen und einem Body, optional gefolgt von einem Semikolon.
A file_scoped_namespace_declaration besteht aus dem Schlüsselwort namespace
, gefolgt von einem Namespace-Namen, einem Semikolon und einer optionalen Liste von extern_alias_directives, using_directives und typ_deklarations.
namespace_declaration
: 'namespace' qualified_identifier namespace_body ';'?
;
file_scoped_namespace_declaration
: 'namespace' qualified_identifier ';' extern_alias_directive* using_directive* type_declaration*
;
... unchanged ...
... unverändert...
Die beiden oben genannten Namespacedeklarationen tragen zum selben Deklarationsraum bei, was in diesem Fall zur Deklaration von zwei Klassen mit den vollqualifizierten Namen N1.N2.A
und N1.N2.B
führt. Da die beiden Deklarationen zum selben Deklarationsraum beitragen, wäre es ein Fehler, wenn jede eine Deklaration eines Mitglieds mit demselben Namen enthielte.
A file_scoped_namespace_declaration erlaubt es, eine Namespace-Deklaration zu schreiben, ohne den { ... }
blockieren. Zum Beispiel:
extern alias A;
namespace Name;
using B;
class C
{
}
ist semantisch äquivalent zu
extern alias A;
namespace Name
{
using B;
class C
{
}
}
Genauer gesagt, ein file_scoped_namespace_declaration wird genauso behandelt wie ein namespace_declaration an der gleichen Stelle im Kompilier-Einheit mit demselben qualifizierter_Identifikator. Die extern_alias_directives, using_directives und typ_deklarations davon file_scoped_namespace_declaration verhalten sich so, als wären sie in der gleichen Reihenfolge innerhalb der Namensraum_Körper davon namespace_declaration.
Eine Quelldatei kann nicht beides enthalten, eine file_scoped_namespace_declaration und eine namespace_declaration. Eine Quelldatei kann nicht mehrere file_scoped_namespace_declarations. A Kompilier-Einheit kann nicht beides enthalten, ein file_scoped_namespace_declaration und jede oberste Ebene Anweisungs. typ_deklarations kann nicht vor einer file_scoped_namespace_declaration.
Extern aliases (Externe Aliase)
... unverändert...
C# feature specifications