NamespacesNamespaces

C#-Programme werden mithilfe von Namespaces organisiert.C# programs are organized using namespaces. Namespaces werden sowohl als internes Organisationssystem für ein Programm als auch als "externes" Organisationssystem verwendet – eine Methode zur Darstellung von Programmelementen, die für andere Programme verfügbar gemacht werden.Namespaces are used both as an "internal" organization system for a program, and as an "external" organization system—a way of presenting program elements that are exposed to other programs.

Using-Direktiven (using-Direktiven) werden bereitgestellt, um die Verwendung von Namespaces zu vereinfachen.Using directives (Using directives) are provided to facilitate the use of namespaces.

Compilation units (Kompilationseinheiten)Compilation units

Eine compilation_unit die die Gesamtstruktur einer Quelldatei definiert.A compilation_unit defines the overall structure of a source file. Eine Kompilierungseinheit besteht aus null oder mehr using_directive s, gefolgt von 0 (null) oder mehr global_attributes gefolgt von 0 (null) oder mehr namespace_member_declaration s.A compilation unit consists of zero or more using_directive s followed by zero or more global_attributes followed by zero or more namespace_member_declaration s.

compilation_unit
    : extern_alias_directive* using_directive* global_attributes? namespace_member_declaration*
    ;

Ein c#-Programm besteht aus einer oder mehreren Kompilierungs Einheiten, die jeweils in einer separaten Quelldatei enthalten sind.A C# program consists of one or more compilation units, each contained in a separate source file. Wenn ein c#-Programm kompiliert wird, werden alle Kompilierungs Einheiten zusammen verarbeitet.When a C# program is compiled, all of the compilation units are processed together. Daher können Kompilierungs Einheiten voneinander abhängig sein, möglicherweise zirkulär.Thus, compilation units can depend on each other, possibly in a circular fashion.

Die using_directive s einer Kompilierungseinheit wirken sich auf die global_attributes und namespace_member_declaration en dieser Kompilierungseinheit aus, haben aber keine Auswirkungen auf andere Kompilierungs Einheiten.The using_directive s of a compilation unit affect the global_attributes and namespace_member_declaration s of that compilation unit, but have no effect on other compilation units.

Die global_attributes (Attribute) einer Kompilierungseinheit erlauben die Spezifikation von Attributen für die Zielassembly und das Zielmodul.The global_attributes (Attributes) of a compilation unit permit the specification of attributes for the target assembly and module. Assemblys und Module fungieren als physische Container für-Typen.Assemblies and modules act as physical containers for types. Eine Assembly besteht möglicherweise aus mehreren physisch getrennten Modulen.An assembly may consist of several physically separate modules.

Die namespace_member_declaration en der einzelnen Kompilierungs Einheiten eines Programms tragen Member zu einem einzelnen Deklarations Bereich bei, der als globaler Namespace bezeichnet wird.The namespace_member_declaration s of each compilation unit of a program contribute members to a single declaration space called the global namespace. Beispiel:For example:

Datei A.cs :File A.cs:

class A {}

Datei B.cs :File B.cs:

class B {}

Die beiden Kompilierungs Einheiten tragen zum einzelnen globalen Namespace bei, in diesem Fall werden zwei Klassen mit den voll qualifizierten Namen A und deklariert B .The two compilation units contribute to the single global namespace, in this case declaring two classes with the fully qualified names A and B. Da die beiden Kompilierungs Einheiten zum selben Deklarations Bereich beitragen, wäre ein Fehler aufgetreten, wenn jede eine Deklaration eines Members mit dem gleichen Namen enthielt.Because the two compilation units contribute to the same declaration space, it would have been an error if each contained a declaration of a member with the same name.

NamespacedeklarationenNamespace declarations

Ein namespace_declaration besteht aus dem Schlüsselwort namespace , gefolgt von einem Namespace Namen und einem Text, gefolgt von einem Semikolon.A namespace_declaration consists of the keyword namespace, followed by a namespace name and body, optionally followed by a semicolon.

namespace_declaration
    : 'namespace' qualified_identifier namespace_body ';'?
    ;

qualified_identifier
    : identifier ('.' identifier)*
    ;

namespace_body
    : '{' extern_alias_directive* using_directive* namespace_member_declaration* '}'
    ;

Eine namespace_declaration kann als Deklaration der obersten Ebene in einer compilation_unit oder als Element Deklaration innerhalb eines anderen namespace_declaration auftreten.A namespace_declaration may occur as a top-level declaration in a compilation_unit or as a member declaration within another namespace_declaration. Wenn eine namespace_declaration als Deklaration der obersten Ebene in einer compilation_unit auftritt, wird der Namespace zu einem Member des globalen Namespace.When a namespace_declaration occurs as a top-level declaration in a compilation_unit, the namespace becomes a member of the global namespace. Wenn ein namespace_declaration in einem anderen namespace_declaration auftritt, wird der innere Namespace zu einem Member des äußeren Namespace.When a namespace_declaration occurs within another namespace_declaration, the inner namespace becomes a member of the outer namespace. In beiden Fällen muss der Name eines Namespace innerhalb des enthaltenden Namespace eindeutig sein.In either case, the name of a namespace must be unique within the containing namespace.

Namespaces sind implizit, public und die Deklaration eines Namespace darf keine Zugriffsmodifizierer enthalten.Namespaces are implicitly public and the declaration of a namespace cannot include any access modifiers.

Innerhalb einer namespace_body importieren die optionalen using_directive s die Namen von anderen Namespaces, Typen und Membern, sodass direkt anstelle von qualifizierten Namen auf Sie verwiesen werden kann.Within a namespace_body, the optional using_directive s import the names of other namespaces, types and members, allowing them to be referenced directly instead of through qualified names. Die optionalen namespace_member_declaration s tragen Member zum Deklarations Raum des Namespace bei.The optional namespace_member_declaration s contribute members to the declaration space of the namespace. Beachten Sie, dass alle using_directive s vor allen Member-Deklarationen angezeigt werden müssen.Note that all using_directive s must appear before any member declarations.

Der qualified_identifier eines namespace_declaration kann ein einzelner Bezeichner oder eine Sequenz von Bezeichnern sein, die durch ""-Token getrennt sind . .The qualified_identifier of a namespace_declaration may be a single identifier or a sequence of identifiers separated by "." tokens. Das zweite Formular ermöglicht einem Programm, einen geschachtelten Namespace zu definieren, ohne dass mehrere Namespace Deklarationen lexikalisch verschachtelt werden.The latter form permits a program to define a nested namespace without lexically nesting several namespace declarations. Beispiel:For example,

namespace N1.N2
{
    class A {}

    class B {}
}

ist semantisch äquivalent zuis semantically equivalent to

namespace N1
{
    namespace N2
    {
        class A {}

        class B {}
    }
}

Namespaces sind offen, und zwei Namespace Deklarationen mit demselben voll qualifizierten Namen tragen zum selben Deklarations Bereich bei (Deklarationen).Namespaces are open-ended, and two namespace declarations with the same fully qualified name contribute to the same declaration space (Declarations). Im BeispielIn the example

namespace N1.N2
{
    class A {}
}

namespace N1.N2
{
    class B {}
}

die beiden oben genannten Namespace Deklarationen tragen zum selben Deklarations Bereich bei, in diesem Fall werden zwei Klassen mit den voll qualifizierten Namen N1.N2.A und deklariert N1.N2.B .the two namespace declarations above contribute to the same declaration space, in this case declaring two classes with the fully qualified names N1.N2.A and N1.N2.B. Da die beiden Deklarationen zum gleichen Deklarations Bereich beitragen, wäre es ein Fehler, wenn jede eine Deklaration eines Members mit dem gleichen Namen enthielt.Because the two declarations contribute to the same declaration space, it would have been an error if each contained a declaration of a member with the same name.

Extern aliases (Externe Aliase)Extern aliases

Eine extern_alias_directive führt einen Bezeichner ein, der als Alias für einen Namespace fungiert.An extern_alias_directive introduces an identifier that serves as an alias for a namespace. Die Spezifikation des Alias Namespace ist außerhalb des Quellcodes des Programms und gilt auch für die schsted Namespaces des Alias Namespace.The specification of the aliased namespace is external to the source code of the program and applies also to nested namespaces of the aliased namespace.

extern_alias_directive
    : 'extern' 'alias' identifier ';'
    ;

Der Gültigkeitsbereich einer extern_alias_directive erstreckt sich über die using_directive s, global_attributes und namespace_member_declaration n der unmittelbar enthaltenden Kompilierungseinheit oder des Namespace Texts.The scope of an extern_alias_directive extends over the using_directive s, global_attributes and namespace_member_declaration s of its immediately containing compilation unit or namespace body.

Innerhalb einer Kompilierungseinheit oder eines Namespace Texts, der einen extern_alias_directive enthält, kann der durch die extern_alias_directive eingeführte Bezeichner verwendet werden, um auf den Alias Namespace zu verweisen.Within a compilation unit or namespace body that contains an extern_alias_directive, the identifier introduced by the extern_alias_directive can be used to reference the aliased namespace. Es handelt sich um einen Kompilierzeitfehler für den Bezeichner , der das Wort ist global .It is a compile-time error for the identifier to be the word global.

Ein extern_alias_directive der einen Alias innerhalb einer bestimmten Kompilierungseinheit oder eines Namespace Texts verfügbar macht, führt jedoch nicht zu neuen Membern, die dem zugrunde liegenden Deklarations Bereich angehören.An extern_alias_directive makes an alias available within a particular compilation unit or namespace body, but it does not contribute any new members to the underlying declaration space. Anders ausgedrückt: eine extern_alias_directive ist nicht transitiv, sondern wirkt sich nur auf die Kompilierungseinheit oder den Namespace Körper aus, in der Sie auftritt.In other words, an extern_alias_directive is not transitive, but, rather, affects only the compilation unit or namespace body in which it occurs.

Das folgende Programm deklariert und verwendet zwei externe Aliase X : und Y , die jeweils den Stamm einer unterschiedlichen Namespace Hierarchie darstellen:The following program declares and uses two extern aliases, X and Y, each of which represent the root of a distinct namespace hierarchy:

extern alias X;
extern alias Y;

class Test
{
    X::N.A a;
    X::N.B b1;
    Y::N.B b2;
    Y::N.C c;
}

Das Programm deklariert das vorhanden sein der externen Aliase X und Y , aber die tatsächlichen Definitionen der Aliase sind für das Programm extern.The program declares the existence of the extern aliases X and Y, but the actual definitions of the aliases are external to the program. Auf die identisch benannten N.B Klassen kann nun als X.N.B und oder unter Y.N.B Verwendung des Namespace-alias Qualifizierers und verwiesen werden X::N.B Y::N.B .The identically named N.B classes can now be referenced as X.N.B and Y.N.B, or, using the namespace alias qualifier, X::N.B and Y::N.B. Ein Fehler tritt auf, wenn ein Programm einen externen Alias deklariert, für den keine externe Definition bereitgestellt wird.An error occurs if a program declares an extern alias for which no external definition is provided.

using-DirektivenUsing directives

*Using-Direktiven _ vereinfachen die Verwendung von Namespaces und Typen, die in anderen Namespaces definiert sind.*Using directives _ facilitate the use of namespaces and types defined in other namespaces. Using-Direktiven wirken sich auf den namens Auflösungsprozess von _namespace_or_type_name * s (Namespace-und Typnamen) und Simple_name s (simple names) aus, aber im Gegensatz zu Deklarationen tragen using-Direktiven keine neuen Member zu den zugrunde liegenden Deklarations Bereichen der Kompilierungs Einheiten oder Namespaces bei, in denen Sie verwendet werden.Using directives impact the name resolution process of _namespace_or_type_name*s (Namespace and type names) and simple_name s (Simple names), but unlike declarations, using directives do not contribute new members to the underlying declaration spaces of the compilation units or namespaces within which they are used.

using_directive
    : using_alias_directive
    | using_namespace_directive
    | using_static_directive
    ;

Ein using_alias_directive (unter Verwendung von Alias Direktiven) führt einen Alias für einen Namespace oder Typ ein.A using_alias_directive (Using alias directives) introduces an alias for a namespace or type.

Ein using_namespace_directive (unter Verwendung von Namespace Direktiven) importiert die Typmember eines Namespaces.A using_namespace_directive (Using namespace directives) imports the type members of a namespace.

Ein using_static_directive (unter Verwendung statischer Direktiven) importiert die Untertypen und statischen Member eines Typs.A using_static_directive (Using static directives) imports the nested types and static members of a type.

Der Gültigkeitsbereich einer using_directive erstreckt sich über die namespace_member_declaration s der unmittelbar enthaltenden Kompilierungseinheit oder des Namespace Texts.The scope of a using_directive extends over the namespace_member_declaration s of its immediately containing compilation unit or namespace body. Der Gültigkeitsbereich einer using_directive enthält nicht den Peer using_directive s.The scope of a using_directive specifically does not include its peer using_directive s. Daher wirken sich die Peer- using_directive s nicht gegenseitig aus, und die Reihenfolge, in der Sie geschrieben werden, ist unerheblich.Thus, peer using_directive s do not affect each other, and the order in which they are written is insignificant.

Using-Alias DirektivenUsing alias directives

Eine using_alias_directive führt einen Bezeichner ein, der als Alias für einen Namespace oder Typ innerhalb der unmittelbar einschließenden Kompilierungseinheit oder des Namespace Texts fungiert.A using_alias_directive introduces an identifier that serves as an alias for a namespace or type within the immediately enclosing compilation unit or namespace body.

using_alias_directive
    : 'using' identifier '=' namespace_or_type_name ';'
    ;

Innerhalb von Element Deklarationen in einer Kompilierungseinheit oder einem Namespace Text, der eine using_alias_directive enthält, kann der durch die using_alias_directive eingeführte Bezeichner verwendet werden, um auf den angegebenen Namespace oder Typ zu verweisen.Within member declarations in a compilation unit or namespace body that contains a using_alias_directive, the identifier introduced by the using_alias_directive can be used to reference the given namespace or type. Beispiel:For example:

namespace N1.N2
{
    class A {}
}

namespace N3
{
    using A = N1.N2.A;

    class B: A {}
}

Darüber hinaus ist innerhalb von Element Deklarationen im- N3 Namespace A ein Alias für N1.N2.A , und die-Klasse wird daher N3.B von der-Klasse abgeleitet N1.N2.A .Above, within member declarations in the N3 namespace, A is an alias for N1.N2.A, and thus class N3.B derives from class N1.N2.A. Sie können denselben Effekt erzielen, indem Sie einen Alias R für erstellen N1.N2 und dann auf verweisen R.A :The same effect can be obtained by creating an alias R for N1.N2 and then referencing R.A:

namespace N3
{
    using R = N1.N2;

    class B: R.A {}
}

Der Bezeichner eines using_alias_directive muss innerhalb des Deklarations Bereichs der Kompilierungseinheit oder des Namespaces eindeutig sein, der die using_alias_directive sofort enthält.The identifier of a using_alias_directive must be unique within the declaration space of the compilation unit or namespace that immediately contains the using_alias_directive. Beispiel:For example:

namespace N3
{
    class A {}
}

namespace N3
{
    using A = N1.N2.A;        // Error, A already exists
}

Oben N3 enthält bereits einen Member A , sodass es sich um einen Kompilierzeitfehler für ein using_alias_directive zur Verwendung dieses Bezeichners handelt.Above, N3 already contains a member A, so it is a compile-time error for a using_alias_directive to use that identifier. Ebenso ist es ein Kompilierzeitfehler für mindestens zwei using_alias_directive s im gleichen Kompilierungs-oder Namespace Text, um Aliase mit dem gleichen Namen zu deklarieren.Likewise, it is a compile-time error for two or more using_alias_directive s in the same compilation unit or namespace body to declare aliases by the same name.

Ein using_alias_directive der einen Alias innerhalb einer bestimmten Kompilierungseinheit oder eines Namespace Texts verfügbar macht, bringt jedoch keine neuen Member in den zugrunde liegenden Deklarations Bereich.A using_alias_directive makes an alias available within a particular compilation unit or namespace body, but it does not contribute any new members to the underlying declaration space. Anders ausgedrückt: eine using_alias_directive ist nicht transitiv, sondern wirkt sich nur auf die Kompilierungseinheit oder den Namespace Körper aus, in der Sie auftritt.In other words, a using_alias_directive is not transitive but rather affects only the compilation unit or namespace body in which it occurs. Im BeispielIn the example

namespace N3
{
    using R = N1.N2;
}

namespace N3
{
    class B: R.A {}            // Error, R unknown
}

der Bereich der using_alias_directive , der nur in den Element R Deklarationen im Namespace Text erweitert, in dem er enthalten ist, R ist in der zweiten Namespace Deklaration unbekannt.the scope of the using_alias_directive that introduces R only extends to member declarations in the namespace body in which it is contained, so R is unknown in the second namespace declaration. Das Platzieren des using_alias_directive in der enthaltenden Kompilierungseinheit bewirkt jedoch, dass der Alias in beiden Namespace Deklarationen verfügbar wird:However, placing the using_alias_directive in the containing compilation unit causes the alias to become available within both namespace declarations:

using R = N1.N2;

namespace N3
{
    class B: R.A {}
}

namespace N3
{
    class C: R.A {}
}

Ebenso wie reguläre Elemente werden die Namen, die von using_alias_directive s eingeführt werden, durch ähnlich benannte Member in den in einem Bereich genannten Bereichen ausgeblendet.Just like regular members, names introduced by using_alias_directive s are hidden by similarly named members in nested scopes. Im BeispielIn the example

using R = N1.N2;

namespace N3
{
    class R {}

    class B: R.A {}        // Error, R has no member A
}

der Verweis auf R.A in der Deklaration von B verursacht einen Kompilierzeitfehler R , da auf N3.R und nicht auf verwiesen wird N1.N2 .the reference to R.A in the declaration of B causes a compile-time error because R refers to N3.R, not N1.N2.

Die Reihenfolge, in der using_alias_directive s geschrieben werden, hat keine Bedeutung, und die Auflösung des namespace_or_type_name , auf das von einer using_alias_directive verwiesen wird, wird nicht von der using_alias_directive selbst oder von anderen using_directive s in der direkt enthaltenden Kompilierungseinheit oder im Namespace Text beeinflusst.The order in which using_alias_directive s are written has no significance, and resolution of the namespace_or_type_name referenced by a using_alias_directive is not affected by the using_alias_directive itself or by other using_directive s in the immediately containing compilation unit or namespace body. Anders ausgedrückt: die namespace_or_type_name eines using_alias_directive wird so aufgelöst, als ob die unmittelbar enthaltende Kompilierungseinheit oder der Namespace Körper keine using_directive s hat.In other words, the namespace_or_type_name of a using_alias_directive is resolved as if the immediately containing compilation unit or namespace body had no using_directive s. Eine using_alias_directive kann jedoch von extern_alias_directive s in der direkt enthaltenden Kompilierungseinheit oder dem Namespace Text betroffen sein.A using_alias_directive may however be affected by extern_alias_directive s in the immediately containing compilation unit or namespace body. Im BeispielIn the example

namespace N1.N2 {}

namespace N3
{
    extern alias E;

    using R1 = E.N;        // OK

    using R2 = N1;         // OK

    using R3 = N1.N2;      // OK

    using R4 = R2.N2;      // Error, R2 unknown
}

der letzte using_alias_directive führt zu einem Kompilierzeitfehler, da der erste using_alias_directive nicht beeinträchtigt wird.the last using_alias_directive results in a compile-time error because it is not affected by the first using_alias_directive. Der erste using_alias_directive führt nicht zu einem Fehler, da der Bereich des extern-Alias E den using_alias_directive enthält.The first using_alias_directive does not result in an error since the scope of the extern alias E includes the using_alias_directive.

Ein using_alias_directive kann einen Alias für einen beliebigen Namespace oder Typ erstellen, einschließlich des Namespaces, in dem er angezeigt wird, sowie eines beliebigen Namespaces oder Typs, der in diesem Namespace geschachtelt ist.A using_alias_directive can create an alias for any namespace or type, including the namespace within which it appears and any namespace or type nested within that namespace.

Der Zugriff auf einen Namespace oder Typ über einen Alias ergibt genau dasselbe Ergebnis wie der Zugriff auf diesen Namespace oder Typ über den deklarierten Namen.Accessing a namespace or type through an alias yields exactly the same result as accessing that namespace or type through its declared name. Beispiel:For example, given

namespace N1.N2
{
    class A {}
}

namespace N3
{
    using R1 = N1;
    using R2 = N1.N2;

    class B
    {
        N1.N2.A a;            // refers to N1.N2.A
        R1.N2.A b;            // refers to N1.N2.A
        R2.A c;               // refers to N1.N2.A
    }
}

die Namen N1.N2.A , R1.N2.A und R2.A sind äquivalent, und alle verweisen auf die-Klasse, deren voll qualifizierter Name ist N1.N2.A .the names N1.N2.A, R1.N2.A, and R2.A are equivalent and all refer to the class whose fully qualified name is N1.N2.A.

Die Verwendung von Aliasen kann einen geschlossenen konstruierten Typ benennen, aber keine ungebundene generische Typdeklaration benennen, ohne Typargumente anzugeben.Using aliases can name a closed constructed type, but cannot name an unbound generic type declaration without supplying type arguments. Beispiel:For example:

namespace N1
{
    class A<T>
    {
        class B {}
    }
}

namespace N2
{
    using W = N1.A;          // Error, cannot name unbound generic type

    using X = N1.A.B;        // Error, cannot name unbound generic type

    using Y = N1.A<int>;     // Ok, can name closed constructed type

    using Z<T> = N1.A<T>;    // Error, using alias cannot have type parameters
}

Using-namespace DirektivenUsing namespace directives

Ein using_namespace_directive importiert die in einem Namespace enthaltenen Typen in den unmittelbar einschließenden Kompilierungs Einheits-oder Namespace Text, sodass der Bezeichner jedes Typs ohne Qualifizierung verwendet werden kann.A using_namespace_directive imports the types contained in a namespace into the immediately enclosing compilation unit or namespace body, enabling the identifier of each type to be used without qualification.

using_namespace_directive
    : 'using' namespace_name ';'
    ;

Innerhalb von Element Deklarationen in einer Kompilierungseinheit oder einem Namespace Text, der eine using_namespace_directive enthält, kann auf die im angegebenen Namespace enthaltenen Typen direkt verwiesen werden.Within member declarations in a compilation unit or namespace body that contains a using_namespace_directive, the types contained in the given namespace can be referenced directly. Beispiel:For example:

namespace N1.N2
{
    class A {}
}

namespace N3
{
    using N1.N2;

    class B: A {}
}

Darüber hinaus sind innerhalb von Element Deklarationen im- N3 Namespace die Typmember von N1.N2 direkt verfügbar, und daher wird die-Klasse von der- N3.B Klasse abgeleitet N1.N2.A .Above, within member declarations in the N3 namespace, the type members of N1.N2 are directly available, and thus class N3.B derives from class N1.N2.A.

Ein- using_namespace_directive importiert die Typen, die im angegebenen Namespace enthalten sind, importiert jedoch nicht die schsted Namespaces.A using_namespace_directive imports the types contained in the given namespace, but specifically does not import nested namespaces. Im BeispielIn the example

namespace N1.N2
{
    class A {}
}

namespace N3
{
    using N1;

    class B: N2.A {}        // Error, N2 unknown
}

der using_namespace_directive importiert die Typen, die in enthalten N1 sind, jedoch nicht die in geschbten Namespaces N1 .the using_namespace_directive imports the types contained in N1, but not the namespaces nested in N1. Folglich führt der Verweis auf N2.A in der Deklaration von zu B einem Kompilierzeitfehler, da sich keine Member mit dem Namen im Gültigkeits N2 Bereich befinden.Thus, the reference to N2.A in the declaration of B results in a compile-time error because no members named N2 are in scope.

Im Gegensatz zu einem using_alias_directive kann ein using_namespace_directive Typen importieren, deren Bezeichner bereits in der einschließenden Kompilierungseinheit oder im Namespace Körper definiert sind.Unlike a using_alias_directive, a using_namespace_directive may import types whose identifiers are already defined within the enclosing compilation unit or namespace body. Tatsächlich werden Namen, die von einem using_namespace_directive importiert werden, durch ähnlich benannte Member in der einschließenden Kompilierungseinheit oder im Namespace Körper ausgeblendet.In effect, names imported by a using_namespace_directive are hidden by similarly named members in the enclosing compilation unit or namespace body. Beispiel:For example:

namespace N1.N2
{
    class A {}

    class B {}
}

namespace N3
{
    using N1.N2;

    class A {}
}

Hier bezieht sich innerhalb von Element Deklarationen im- N3 Namespace A auf N3.A anstelle von N1.N2.A .Here, within member declarations in the N3 namespace, A refers to N3.A rather than N1.N2.A.

Wenn mehr als ein Namespace oder Typ, der von using_namespace_directive s oder using_static_directive s in derselben Kompilierungseinheit oder im gleichen Namespace Körper importiert wurde, Typen mit demselben Namen enthalten, werden Verweise auf diesen Namen als TYPE_NAME als mehrdeutig eingestuft.When more than one namespace or type imported by using_namespace_directive s or using_static_directive s in the same compilation unit or namespace body contain types by the same name, references to that name as a type_name are considered ambiguous. Im BeispielIn the example

namespace N1
{
    class A {}
}

namespace N2
{
    class A {}
}

namespace N3
{
    using N1;

    using N2;

    class B: A {}                // Error, A is ambiguous
}

N1und N2 enthalten einen-Member A , und da N3 beide importiert, A ist der Verweis auf in N3 ein Kompilierzeitfehler.both N1 and N2 contain a member A, and because N3 imports both, referencing A in N3 is a compile-time error. In dieser Situation kann der Konflikt entweder durch Qualifizierung von Verweisen auf A oder durch Einführen eines using_alias_directive gelöst werden, der einen bestimmten Wert auswählt A .In this situation, the conflict can be resolved either through qualification of references to A, or by introducing a using_alias_directive that picks a particular A. Beispiel:For example:

namespace N3
{
    using N1;

    using N2;

    using A = N1.A;

    class B: A {}                // A means N1.A
}

Wenn mehr als ein Namespace oder ein Typ, der von using_namespace_directive s oder using_static_directive s in derselben Kompilierungseinheit oder im gleichen Namespace Körper importiert wurde, Typen oder Member mit demselben Namen enthalten, werden Verweise auf diesen Namen als Simple_name als mehrdeutig eingestuft.Furthermore, when more than one namespace or type imported by using_namespace_directive s or using_static_directive s in the same compilation unit or namespace body contain types or members by the same name, references to that name as a simple_name are considered ambiguous. Im BeispielIn the example

namespace N1
{
    class A {}
}

class C
{
    public static int A;
}

namespace N2
{
    using N1;
    using static C;

    class B
    {
        void M() 
        { 
            A a = new A();   // Ok, A is unambiguous as a type-name
            A.Equals(2);     // Error, A is ambiguous as a simple-name
        }
    }
}

N1 enthält einen Typmember A und C enthält ein statisches Feld A , und da N2 sowohl als auch Verweise A als Simple_name nicht eindeutig und ein Kompilierzeitfehler ist.N1 contains a type member A, and C contains a static field A, and because N2 imports both, referencing A as a simple_name is ambiguous and a compile-time error.

Wie bei einer using_alias_directive trägt ein using_namespace_directive keine neuen Member zum zugrunde liegenden Deklarations Bereich der Kompilierungseinheit oder des Namespace bei, sondern wirkt sich nur auf die Kompilierungseinheit oder den Namespace Text aus, in dem er angezeigt wird.Like a using_alias_directive, a using_namespace_directive does not contribute any new members to the underlying declaration space of the compilation unit or namespace, but rather affects only the compilation unit or namespace body in which it appears.

Die namespace_name , auf die von einem using_namespace_directive verwiesen wird, wird auf die gleiche Weise aufgelöst wie die namespace_or_type_name , auf die von einem using_alias_directive verwiesen wirdThe namespace_name referenced by a using_namespace_directive is resolved in the same way as the namespace_or_type_name referenced by a using_alias_directive. Daher wirken sich using_namespace_directive s in derselben Kompilierungseinheit oder im gleichen Namespace Text nicht gegenseitig aus und können in beliebiger Reihenfolge geschrieben werden.Thus, using_namespace_directive s in the same compilation unit or namespace body do not affect each other and can be written in any order.

Verwenden statischer DirektivenUsing static directives

Ein using_static_directive importiert die in einer Typdeklaration enthaltenen, in eine Typdeklaration enthaltenen, in eine Typdeklaration enthaltenen, in die unmittelbar einschließenden Kompilierungseinheit oder im Namespace Text enthaltenen statischen MemberA using_static_directive imports the nested types and static members contained directly in a type declaration into the immediately enclosing compilation unit or namespace body, enabling the identifier of each member and type to be used without qualification.

using_static_directive
    : 'using' 'static' type_name ';'
    ;

Innerhalb von Element Deklarationen in einer Kompilierungseinheit oder einem Namespace Text, der eine using_static_directive enthält, kann direkt auf die zugänglichen geschachtelten Typen und statischen Member (mit Ausnahme von Erweiterungs Methoden) verwiesen werden, die direkt in der Deklaration des angegebenen Typs enthalten sind.Within member declarations in a compilation unit or namespace body that contains a using_static_directive, the accessible nested types and static members (except extension methods) contained directly in the declaration of the given type can be referenced directly. Beispiel:For example:

namespace N1
{
    class A 
    {
        public class B{}
        public static B M(){ return new B(); }
    }
}

namespace N2
{
    using static N1.A;
    class C
    {
        void N() { B b = M(); }
    }
}

Darüber hinaus sind innerhalb von Element Deklarationen im N2 -Namespace die statischen Member und geschachtelten Typen von N1.A direkt verfügbar. daher N kann die-Methode auf die B -und-Member von verweisen M N1.A .Above, within member declarations in the N2 namespace, the static members and nested types of N1.A are directly available, and thus the method N is able to reference both the B and M members of N1.A.

Ein- using_static_directive importiert Erweiterungs Methoden speziell nicht direkt als statische Methoden, stellt Sie jedoch für den Aufruf der Erweiterungsmethode (Erweiterungs Methodenaufrufe) zur Verfügung.A using_static_directive specifically does not import extension methods directly as static methods, but makes them available for extension method invocation (Extension method invocations). Im BeispielIn the example

namespace N1 
{
    static class A 
    {
        public static void M(this string s){}
    }
}

namespace N2
{
    using static N1.A;

    class B
    {
        void N() 
        {
            M("A");      // Error, M unknown
            "B".M();     // Ok, M known as extension method
            N1.A.M("C"); // Ok, fully qualified
        }
    }
}

der using_static_directive importiert die M in enthaltene Erweiterungsmethode N1.A , jedoch nur als Erweiterungsmethode.the using_static_directive imports the extension method M contained in N1.A, but only as an extension method. Folglich führt der erste Verweis auf M im Text von zu B.N einem Kompilierzeitfehler, da sich keine Member mit dem Namen im Gültigkeits M Bereich befinden.Thus, the first reference to M in the body of B.N results in a compile-time error because no members named M are in scope.

Ein using_static_directive nur Member und Typen importiert, die direkt im angegebenen Typ deklariert sind, nicht Elemente und Typen, die in Basisklassen deklariert werden.A using_static_directive only imports members and types declared directly in the given type, not members and types declared in base classes.

TODO: BeispielTODO: Example

Mehrdeutigkeiten zwischen mehreren using_namespace_directives und using_static_directives werden unter using namespace-Direktivenerläutert.Ambiguities between multiple using_namespace_directives and using_static_directives are discussed in Using namespace directives.

Namespace members (Namespacemember)Namespace members

Ein namespace_member_declaration ist entweder namespace_declaration (Namespace Deklarationen) oder eine type_declaration (Typdeklarationen).A namespace_member_declaration is either a namespace_declaration (Namespace declarations) or a type_declaration (Type declarations).

namespace_member_declaration
    : namespace_declaration
    | type_declaration
    ;

Eine Kompilierungseinheit oder ein Namespace Text kann namespace_member_declaration s enthalten, und solche Deklarationen tragen neue Member zum zugrunde liegenden Deklarations Bereich der enthaltenden Kompilierungseinheit oder des Namespace Texts bei.A compilation unit or a namespace body can contain namespace_member_declaration s, and such declarations contribute new members to the underlying declaration space of the containing compilation unit or namespace body.

Type declarations (Typdeklarationen)Type declarations

Eine type_declaration ist eine class_declaration (Klassen Deklarationen), eine struct_declaration (Struktur Deklarationen), eine interface_declaration (Schnittstellen Deklarationen), eine enum_declaration (Enumerationsdeklarationen ) odereine delegate_declaration (Delegatdeklarationen).A type_declaration is a class_declaration (Class declarations), a struct_declaration (Struct declarations), an interface_declaration (Interface declarations), an enum_declaration (Enum declarations), or a delegate_declaration (Delegate declarations).

type_declaration
    : class_declaration
    | struct_declaration
    | interface_declaration
    | enum_declaration
    | delegate_declaration
    ;

Eine type_declaration kann als Deklaration der obersten Ebene in einer Kompilierungseinheit oder als Element Deklaration innerhalb eines Namespace, einer Klasse oder einer Struktur auftreten.A type_declaration can occur as a top-level declaration in a compilation unit or as a member declaration within a namespace, class, or struct.

Wenn eine Typdeklaration für einen Typ T als Deklaration der obersten Ebene in einer Kompilierungseinheit auftritt, ist der voll qualifizierte Name des neu deklarierten Typs einfach T .When a type declaration for a type T occurs as a top-level declaration in a compilation unit, the fully qualified name of the newly declared type is simply T. Wenn eine Typdeklaration für einen Typ T innerhalb eines Namespace, einer Klasse oder einer Struktur auftritt, ist der voll qualifizierte Name des neu deklarierten Typs N.T , wobei N der voll qualifizierte Name des enthaltenden Namespace, der Klasse oder der Struktur ist.When a type declaration for a type T occurs within a namespace, class, or struct, the fully qualified name of the newly declared type is N.T, where N is the fully qualified name of the containing namespace, class, or struct.

Ein innerhalb einer Klasse oder Struktur deklarierter Typ wird als geschachtelter Typ (geschachtelteTypen) bezeichnet.A type declared within a class or struct is called a nested type (Nested types).

Die zulässigen Zugriffsmodifizierer und der Standard Zugriff für eine Typdeklaration sind abhängig von dem Kontext, in dem die Deklaration stattfindet (alsBarrierefreiheit deklariert):The permitted access modifiers and the default access for a type declaration depend on the context in which the declaration takes place (Declared accessibility):

  • In Kompilierungs Einheiten oder Namespaces deklarierte Typen können- public oder- internal Zugriff besitzen.Types declared in compilation units or namespaces can have public or internal access. Der Standardwert ist internal Access.The default is internal access.
  • In Klassen deklarierte Typen können über public , protected internal , protected , internal oder private Zugriff verfügen.Types declared in classes can have public, protected internal, protected, internal, or private access. Der Standardwert ist private Access.The default is private access.
  • In Strukturen deklarierte Typen können über public , internal oder private Zugriff verfügen.Types declared in structs can have public, internal, or private access. Der Standardwert ist private Access.The default is private access.

Namespace alias qualifiers (Qualifizierer für Namespacealiase)Namespace alias qualifiers

Der Namespacealias-Qualifizierer :: ermöglicht es, sicherzustellen, dass die Suche nach Typnamen durch die Einführung neuer Typen und Member nicht beeinträchtigt wird.The namespace alias qualifier :: makes it possible to guarantee that type name lookups are unaffected by the introduction of new types and members. Der Namespacealias-Qualifizierer wird immer zwischen zwei bezeichern angezeigt, die als linke und Rechte Bezeichner bezeichnet werden.The namespace alias qualifier always appears between two identifiers referred to as the left-hand and right-hand identifiers. Im Gegensatz zum regulären . Qualifizierer wird der linke Bezeichner des :: Qualifizierers nur als extern oder using-Alias gesucht.Unlike the regular . qualifier, the left-hand identifier of the :: qualifier is looked up only as an extern or using alias.

Ein qualified_alias_member wird wie folgt definiert:A qualified_alias_member is defined as follows:

qualified_alias_member
    : identifier '::' identifier type_argument_list?
    ;

Eine qualified_alias_member kann als namespace_or_type_name (Namespace-und Typnamen) oder als Linker Operand in einem member_access (Member Access) verwendet werden.A qualified_alias_member can be used as a namespace_or_type_name (Namespace and type names) or as the left operand in a member_access (Member access).

Ein qualified_alias_member hat eine von zwei Formen:A qualified_alias_member has one of two forms:

  • N::I<A1, ..., Ak>, wobei N und I Identifizierer darstellen und <A1, ..., Ak> eine Typargument Liste ist.N::I<A1, ..., Ak>, where N and I represent identifiers, and <A1, ..., Ak> is a type argument list. ( K ist immer mindestens ein.)(K is always at least one.)
  • N::I, wobei N und I Bezeichner darstellen.N::I, where N and I represent identifiers. (In diesem Fall gilt K als 0 (null).)(In this case, K is considered to be zero.)

Mit dieser Notation wird die Bedeutung eines qualified_alias_member wie folgt bestimmt:Using this notation, the meaning of a qualified_alias_member is determined as follows:

  • Wenn N der Bezeichner ist global , wird der globale Namespace durchsucht I :If N is the identifier global, then the global namespace is searched for I:

    • Wenn der globale-Namespace einen Namespace mit dem Namen  I und 0 (null) enthält K , verweist der qualified_alias_member auf diesen Namespace.If the global namespace contains a namespace named I and K is zero, then the qualified_alias_member refers to that namespace.
    • Wenn der globale Namespace andernfalls einen nicht generischen Typ mit dem Namen  I und K 0 (null) enthält, verweist der qualified_alias_member auf diesen Typ.Otherwise, if the global namespace contains a non-generic type named I and K is zero, then the qualified_alias_member refers to that type.
    • Wenn der globale Namespace einen Typ mit dem Namen enthält,  I K   der über Typparameter verfügt, verweist der qualified_alias_member auf diesen Typ, der mit den angegebenen Typargumenten erstellt wurde.Otherwise, if the global namespace contains a type named I that has K type parameters, then the qualified_alias_member refers to that type constructed with the given type arguments.
    • Andernfalls ist der qualified_alias_member nicht definiert, und es tritt ein Kompilierzeitfehler auf.Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.
  • Andernfalls werden ab der Namespace Deklaration (Namespace Deklarationen), die sofort die qualified_alias_member enthält (sofern vorhanden), mit jeder einschließenden Namespace Deklaration (sofern vorhanden) und mit der Kompilierungseinheit, die die qualified_alias_member enthält, die folgenden Schritte ausgewertet, bis eine Entität gefunden wird:Otherwise, starting with the namespace declaration (Namespace declarations) immediately containing the qualified_alias_member (if any), continuing with each enclosing namespace declaration (if any), and ending with the compilation unit containing the qualified_alias_member, the following steps are evaluated until an entity is located:

    • Wenn die Namespace Deklaration oder Kompilierungseinheit eine using_alias_directive enthält, die N einem Typ zugeordnet ist, ist die qualified_alias_member nicht definiert, und ein Kompilierzeitfehler tritt auf.If the namespace declaration or compilation unit contains a using_alias_directive that associates N with a type, then the qualified_alias_member is undefined and a compile-time error occurs.
    • Andernfalls, wenn die Namespace Deklaration oder Kompilierungseinheit eine extern_alias_directive oder using_alias_directive enthält, die N einem Namespace zugeordnet ist, dann:Otherwise, if the namespace declaration or compilation unit contains an extern_alias_directive or using_alias_directive that associates N with a namespace, then:
      • Wenn der zugeordnete Namespace N einen Namespace mit dem Namen  I und 0 (null) enthält K , verweist der qualified_alias_member auf diesen Namespace.If the namespace associated with N contains a namespace named I and K is zero, then the qualified_alias_member refers to that namespace.
      • Wenn der Namespace, der zugeordnet N ist, einen nicht generischen Typ mit  I dem Namen und 0 (null) enthält K , verweist der qualified_alias_member auf diesen Typ.Otherwise, if the namespace associated with N contains a non-generic type named I and K is zero, then the qualified_alias_member refers to that type.
      • Wenn der Namespace, der zugeordnet N ist, einen Typ mit  I dem Namen enthält K   , der über Typparameter verfügt, verweist der qualified_alias_member auf diesen Typ, der mit den angegebenen Typargumenten erstellt wurde.Otherwise, if the namespace associated with N contains a type named I that has K type parameters, then the qualified_alias_member refers to that type constructed with the given type arguments.
      • Andernfalls ist der qualified_alias_member nicht definiert, und es tritt ein Kompilierzeitfehler auf.Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.
  • Andernfalls ist der qualified_alias_member nicht definiert, und es tritt ein Kompilierzeitfehler auf.Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.

Beachten Sie, dass die Verwendung des Namespace-alias Qualifizierers mit einem Alias, der auf einen Typ verweist, zu einem KompilierzeitfehlerNote that using the namespace alias qualifier with an alias that references a type causes a compile-time error. Beachten Sie auch, dass die  N Suche im globalen Namespace durchgeführt wird, wenn der Bezeichner ist, und zwar global auch dann, wenn ein Using-Alias global mit einem Typ oder Namespace verknüpft ist.Also note that if the identifier N is global, then lookup is performed in the global namespace, even if there is a using alias associating global with a type or namespace.

Eindeutigkeit von AliasenUniqueness of aliases

Jede Kompilierungseinheit und jeder Namespace Körper verfügen über einen separaten Deklarations Raum für externe Aliase und mithilfe von Aliasen.Each compilation unit and namespace body has a separate declaration space for extern aliases and using aliases. Folglich muss der Name eines externen Alias oder der using-alias innerhalb des Satzes externer Aliase eindeutig sein und Aliase verwenden, die in der direkt enthaltenden Kompilierungseinheit oder im Namespace Körper deklariert sind. ein Alias kann daher denselben Namen wie ein Typ oder Namespace aufweisen, solange er nur mit dem Qualifizierer verwendet wird :: .Thus, while the name of an extern alias or using alias must be unique within the set of extern aliases and using aliases declared in the immediately containing compilation unit or namespace body, an alias is permitted to have the same name as a type or namespace as long as it is used only with the :: qualifier.

Im BeispielIn the example

namespace N
{
    public class A {}

    public class B {}
}

namespace N
{
    using A = System.IO;

    class X
    {
        A.Stream s1;            // Error, A is ambiguous

        A::Stream s2;           // Ok
    }
}

der Name A weist zwei mögliche Bedeutungen im zweiten Namespace Text auf, da sich sowohl die A -Klasse als auch der using-Alias im Gültigkeits A Bereich befinden.the name A has two possible meanings in the second namespace body because both the class A and the using alias A are in scope. Aus diesem Grund A ist die Verwendung von im qualifizierten Namen A.Stream mehrdeutig und bewirkt, dass ein Kompilierzeitfehler auftritt.For this reason, use of A in the qualified name A.Stream is ambiguous and causes a compile-time error to occur. Die Verwendung von A mit dem :: Qualifizierer ist jedoch kein Fehler, da A nur als Namespacealias gesucht wird.However, use of A with the :: qualifier is not an error because A is looked up only as a namespace alias.