Spazi dei nomiNamespaces

I programmi C# sono organizzati usando gli spazi dei nomi.C# programs are organized using namespaces. Gli spazi dei nomi vengono utilizzati sia come sistema aziendale "interno" per un programma che come sistema aziendale esterno, un modo per presentare gli elementi del programma esposti ad altri programmi.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.

Le direttive using (direttive using) vengono fornite per semplificare l'uso degli spazi dei nomi.Using directives (Using directives) are provided to facilitate the use of namespaces.

Unità di compilazioneCompilation units

Una compilation_unit definisce la struttura complessiva di un file di origine.A compilation_unit defines the overall structure of a source file. Un'unità di compilazione è costituita da zero o più using_directive, seguiti da zero o più global_attributes seguito da zero o più 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*
    ;

Un programma C# è costituito da una o più unità di compilazione, ognuna contenuta in un file di origine separato.A C# program consists of one or more compilation units, each contained in a separate source file. Quando viene compilato un programma C#, tutte le unità di compilazione vengono elaborate insieme.When a C# program is compiled, all of the compilation units are processed together. Pertanto, le unità di compilazione possono dipendere l'una dall'altra, possibilmente in modo circolare.Thus, compilation units can depend on each other, possibly in a circular fashion.

Le using_directive di un'unità di compilazione influiscono sul global_attributes e namespace_member_declaration s di tale unità di compilazione, ma non hanno alcun effetto su altre unità di compilazione.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.

Il global_attributes (attributi) di un'unità di compilazione consente di specificare gli attributi per l'assembly e il modulo di destinazione.The global_attributes (Attributes) of a compilation unit permit the specification of attributes for the target assembly and module. Gli assembly e i moduli fungono da contenitori fisici per i tipi.Assemblies and modules act as physical containers for types. Un assembly può essere costituito da diversi moduli fisicamente separati.An assembly may consist of several physically separate modules.

Il namespace_member_declaration s di ogni unità di compilazione di un programma collabora con i membri di un singolo spazio di dichiarazione denominato spazio dei nomi globale.The namespace_member_declaration s of each compilation unit of a program contribute members to a single declaration space called the global namespace. Ad esempio:For example:

File A.cs :File A.cs:

class A {}

File B.cs :File B.cs:

class B {}

Le due unità di compilazione contribuiscono al singolo spazio dei nomi globale, in questo caso la dichiarazione di due classi con i nomi completi A e 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. Poiché le due unità di compilazione contribuiscono allo stesso spazio di dichiarazione, sarebbe stato un errore se ognuna conteneva una dichiarazione di un membro con lo stesso nome.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.

Dichiarazioni degli spazi dei nomiNamespace declarations

Un namespace_declaration è costituito dalla parola chiave namespace , seguita da un nome e da un corpo dello spazio dei nomi, seguito facoltativamente da un punto e virgola.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* '}'
    ;

Un namespace_declaration può verificarsi come dichiarazione di primo livello in una compilation_unit o come dichiarazione di membro all'interno di un altro namespace_declaration.A namespace_declaration may occur as a top-level declaration in a compilation_unit or as a member declaration within another namespace_declaration. Quando un namespace_declaration viene generato come dichiarazione di primo livello in una compilation_unit, lo spazio dei nomi diventa un membro dello spazio dei nomi globale.When a namespace_declaration occurs as a top-level declaration in a compilation_unit, the namespace becomes a member of the global namespace. Quando si verifica un namespace_declaration all'interno di un'altra namespace_declaration, lo spazio dei nomi interno diventa membro dello spazio dei nomi esterno.When a namespace_declaration occurs within another namespace_declaration, the inner namespace becomes a member of the outer namespace. In entrambi i casi, il nome di uno spazio dei nomi deve essere univoco all'interno dello spazio dei nomi che lo contiene.In either case, the name of a namespace must be unique within the containing namespace.

Gli spazi dei nomi sono implicitamente public e la dichiarazione di uno spazio dei nomi non può includere modificatori di accesso.Namespaces are implicitly public and the declaration of a namespace cannot include any access modifiers.

All'interno di un namespace_body, i using_directive facoltativi importano i nomi di altri spazi dei nomi, tipi e membri, consentendo loro di farvi riferimento direttamente anziché tramite nomi completi.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. I namespace_member_declaration facoltativi contribuiscono a fornire membri allo spazio di dichiarazione dello spazio dei nomi.The optional namespace_member_declaration s contribute members to the declaration space of the namespace. Si noti che tutti i using_directive devono essere visualizzati prima delle dichiarazioni dei membri.Note that all using_directive s must appear before any member declarations.

Il qualified_identifier di un namespace_declaration può essere un identificatore singolo o una sequenza di identificatori separati dai . token "".The qualified_identifier of a namespace_declaration may be a single identifier or a sequence of identifiers separated by "." tokens. Il secondo formato consente a un programma di definire uno spazio dei nomi annidato senza nidificare in modo lessicale diverse dichiarazioni dello spazio dei nomi.The latter form permits a program to define a nested namespace without lexically nesting several namespace declarations. Ad esempio,For example,

namespace N1.N2
{
    class A {}

    class B {}
}

è semanticamente equivalente ais semantically equivalent to

namespace N1
{
    namespace N2
    {
        class A {}

        class B {}
    }
}

Gli spazi dei nomi sono aperti e due dichiarazioni dello spazio dei nomi con lo stesso nome completo contribuiscono allo stesso spazio di dichiarazione (dichiarazioni).Namespaces are open-ended, and two namespace declarations with the same fully qualified name contribute to the same declaration space (Declarations). Nell'esempioIn the example

namespace N1.N2
{
    class A {}
}

namespace N1.N2
{
    class B {}
}

le due dichiarazioni dello spazio dei nomi precedenti contribuiscono allo stesso spazio di dichiarazione, in questo caso la dichiarazione di due classi con i nomi completi N1.N2.A e 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. Poiché le due dichiarazioni contribuiscono allo stesso spazio di dichiarazione, sarebbe stato un errore se ognuna conteneva una dichiarazione di un membro con lo stesso nome.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.

Alias externExtern aliases

Un extern_alias_directive introduce un identificatore che funge da alias per uno spazio dei nomi.An extern_alias_directive introduces an identifier that serves as an alias for a namespace. La specifica dello spazio dei nomi con alias è esterna al codice sorgente del programma e si applica anche agli spazi dei nomi annidati dello spazio dei nomi con alias.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 ';'
    ;

L'ambito di un extern_alias_directive si estende su using_directive s, global_attributes e namespace_member_declaration del relativo oggetto immediatamente contenente l'unità di compilazione o il corpo dello spazio dei nomi.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.

All'interno di un'unità di compilazione o di un corpo dello spazio dei nomi che contiene una extern_alias_directive, l'identificatore introdotto dall' extern_alias_directive può essere usato per fare riferimento allo spazio dei nomi con alias.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. Si tratta di un errore in fase di compilazione perché l' identificatore sia la parola global .It is a compile-time error for the identifier to be the word global.

Un extern_alias_directive rende disponibile un alias all'interno di una particolare unità di compilazione o corpo dello spazio dei nomi, ma non fornisce alcun nuovo membro allo spazio di dichiarazione sottostante.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. In altre parole, un extern_alias_directive non è transitivo, ma influiscono solo sull'unità di compilazione o sul corpo dello spazio dei nomi in cui si verifica.In other words, an extern_alias_directive is not transitive, but, rather, affects only the compilation unit or namespace body in which it occurs.

Nel programma seguente vengono dichiarati e utilizzati due alias extern, X e Y , ognuno dei quali rappresenta la radice di una gerarchia di spazi dei nomi distinti: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;
}

Il programma dichiara l'esistenza degli alias extern X e Y , ma le definizioni effettive degli alias sono esterne al programma.The program declares the existence of the extern aliases X and Y, but the actual definitions of the aliases are external to the program. N.BÈ ora possibile fare riferimento alle classi con nome identico come X.N.B and Y.N.B , or, usando il qualificatore alias degli spazi dei nomi X::N.B e 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. Si verifica un errore se un programma dichiara un alias extern per il quale non viene fornita alcuna definizione esterna.An error occurs if a program declares an extern alias for which no external definition is provided.

Direttive usingUsing directives

*Le direttive using _ facilitano l'uso di spazi dei nomi e tipi definiti in altri spazi dei nomi.*Using directives _ facilitate the use of namespaces and types defined in other namespaces. Le direttive using influiscono sul processo di risoluzione dei nomi di _namespace_or_type_name * s (nomi di spazio dei nomi e di tipi) e simple_name s (nomi semplici), ma a differenza delle dichiarazioni, le direttive using non contribuiscono ai nuovi membri degli spazi di dichiarazione sottostanti delle unità di compilazione o degli spazi dei nomi in cui vengono utilizzati.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
    ;

Un using_alias_directive (usando le direttive alias) introduce un alias per uno spazio dei nomi o un tipo.A using_alias_directive (Using alias directives) introduces an alias for a namespace or type.

Un using_namespace_directive (usando le direttive dello spazio dei nomi) importa i membri del tipo di uno spazio dei nomi.A using_namespace_directive (Using namespace directives) imports the type members of a namespace.

Un using_static_directive (mediante direttive statiche) importa i tipi annidati e i membri statici di un tipo.A using_static_directive (Using static directives) imports the nested types and static members of a type.

L'ambito di un using_directive si estende sulle namespace_member_declaration dell'unità di compilazione immediatamente contenitore o del corpo dello spazio dei nomi.The scope of a using_directive extends over the namespace_member_declaration s of its immediately containing compilation unit or namespace body. L'ambito di un using_directive in particolare non include il peer using_directive s.The scope of a using_directive specifically does not include its peer using_directive s. Di conseguenza, i peer using_directive s non interagiscono tra loro e l'ordine in cui vengono scritti non è significativo.Thus, peer using_directive s do not affect each other, and the order in which they are written is insignificant.

Uso delle direttive aliasUsing alias directives

Un using_alias_directive introduce un identificatore che funge da alias per uno spazio dei nomi o un tipo all'interno dell'unità di compilazione o del corpo dello spazio dei nomi che lo contiene immediatamente.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 ';'
    ;

All'interno di dichiarazioni di membri in un'unità di compilazione o in un corpo dello spazio dei nomi che contiene una using_alias_directive, l'identificatore introdotto dall' using_alias_directive può essere usato per fare riferimento allo spazio dei nomi o al tipo specificato.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. Ad esempio:For example:

namespace N1.N2
{
    class A {}
}

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

    class B: A {}
}

In precedenza, all'interno delle dichiarazioni di membro nello N3 spazio dei nomi, A è un alias per N1.N2.A e pertanto la classe N3.B deriva dalla classe 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. È possibile ottenere lo stesso effetto creando un alias R per N1.N2 e quindi facendo riferimento a 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 {}
}

L' identificatore di un using_alias_directive deve essere univoco all'interno dello spazio di dichiarazione dell'unità di compilazione o dello spazio dei nomi che contiene immediatamente l' using_alias_directive.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. Ad esempio:For example:

namespace N3
{
    class A {}
}

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

Sopra, N3 contiene già un membro A , quindi si tratta di un errore in fase di compilazione per un using_alias_directive di usare tale identificatore.Above, N3 already contains a member A, so it is a compile-time error for a using_alias_directive to use that identifier. Analogamente, si tratta di un errore in fase di compilazione per due o più using_alias_directive nella stessa unità di compilazione o corpo dello spazio dei nomi per dichiarare gli alias con lo stesso nome.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.

Un using_alias_directive rende disponibile un alias all'interno di una particolare unità di compilazione o corpo dello spazio dei nomi, ma non fornisce alcun nuovo membro allo spazio di dichiarazione sottostante.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. In altre parole, una using_alias_directive non è transitiva, ma interessa solo l'unità di compilazione o il corpo dello spazio dei nomi in cui si verifica.In other words, a using_alias_directive is not transitive but rather affects only the compilation unit or namespace body in which it occurs. Nell'esempioIn the example

namespace N3
{
    using R = N1.N2;
}

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

l'ambito del using_alias_directive che introduce si R estende solo alle dichiarazioni di membro nel corpo dello spazio dei nomi in cui è contenuto, pertanto R è sconosciuto nella seconda dichiarazione dello spazio dei nomi.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. Tuttavia, inserendo il using_alias_directive nell'unità di compilazione che lo contiene, l'alias diventa disponibile in entrambe le dichiarazioni dello spazio dei nomi: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 {}
}

Proprio come i membri normali, i nomi introdotti da using_alias_directive s sono nascosti da membri denominati in modo analogo negli ambiti annidati.Just like regular members, names introduced by using_alias_directive s are hidden by similarly named members in nested scopes. Nell'esempioIn the example

using R = N1.N2;

namespace N3
{
    class R {}

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

il riferimento a R.A nella dichiarazione di B genera un errore in fase di compilazione perché R fa riferimento a N3.R e non a 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.

L'ordine in cui vengono scritti using_alias_directive s non ha significato e la risoluzione dei namespace_or_type_name a cui fa riferimento un using_alias_directive non è interessata dal using_alias_directive stesso o da altri using_directive nell'unità di compilazione o nel corpo dello spazio dei nomi immediatamente contenitore.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. In altre parole, la namespace_or_type_name di un using_alias_directive viene risolta come se l'unità di compilazione o il corpo dello spazio dei nomi immediatamente contenitore non avesse using_directive s.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. Un using_alias_directive può tuttavia essere influenzato da extern_alias_directive nell'unità di compilazione immediatamente contenitore o nel corpo dello spazio dei nomi.A using_alias_directive may however be affected by extern_alias_directive s in the immediately containing compilation unit or namespace body. Nell'esempioIn 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
}

l'ultimo using_alias_directive genera un errore in fase di compilazione perché non è influenzato dalla prima using_alias_directive.the last using_alias_directive results in a compile-time error because it is not affected by the first using_alias_directive. Il primo using_alias_directive non genera un errore perché l'ambito dell'alias extern E include l' using_alias_directive.The first using_alias_directive does not result in an error since the scope of the extern alias E includes the using_alias_directive.

Un using_alias_directive può creare un alias per qualsiasi spazio dei nomi o tipo, incluso lo spazio dei nomi in cui viene visualizzato e qualsiasi spazio dei nomi o tipo annidato all'interno di tale spazio dei nomi.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.

L'accesso a uno spazio dei nomi o a un tipo tramite un alias produce esattamente lo stesso risultato dell'accesso a tale spazio dei nomi o tipo tramite il nome dichiarato.Accessing a namespace or type through an alias yields exactly the same result as accessing that namespace or type through its declared name. Ad esempio, datoFor 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
    }
}

i nomi N1.N2.A , R1.N2.A e R2.A sono equivalenti e tutti fanno riferimento alla classe il cui nome completo è 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.

L'uso di alias può denominare un tipo costruito chiuso, ma non può assegnare un nome a una dichiarazione di tipo generico non associato senza fornire argomenti di tipo.Using aliases can name a closed constructed type, but cannot name an unbound generic type declaration without supplying type arguments. Ad esempio: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
}

Uso delle direttive NamespaceUsing namespace directives

Un using_namespace_directive importa i tipi contenuti in uno spazio dei nomi nel corpo dell'unità di compilazione o dello spazio dei nomi che lo contiene immediatamente, consentendo l'utilizzo dell'identificatore di ogni tipo senza qualifica.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 ';'
    ;

All'interno di dichiarazioni di membri in un'unità di compilazione o in un corpo dello spazio dei nomi che contiene una using_namespace_directive, è possibile fare riferimento direttamente ai tipi contenuti nello spazio dei nomi specificato.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. Ad esempio:For example:

namespace N1.N2
{
    class A {}
}

namespace N3
{
    using N1.N2;

    class B: A {}
}

In precedenza, all'interno delle dichiarazioni di membri nello N3 spazio dei nomi, i membri del tipo di N1.N2 sono direttamente disponibili e pertanto la classe N3.B deriva dalla classe 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.

Un using_namespace_directive importa i tipi contenuti nello spazio dei nomi specificato, ma in particolare non importa gli spazi dei nomi annidati.A using_namespace_directive imports the types contained in the given namespace, but specifically does not import nested namespaces. Nell'esempioIn the example

namespace N1.N2
{
    class A {}
}

namespace N3
{
    using N1;

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

il using_namespace_directive importa i tipi contenuti in N1 , ma non gli spazi dei nomi annidati in N1 .the using_namespace_directive imports the types contained in N1, but not the namespaces nested in N1. Pertanto, il riferimento a N2.A nella dichiarazione di B genera un errore in fase di compilazione perché nessun membro denominato N2 è nell'ambito.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.

A differenza di un using_alias_directive, un using_namespace_directive può importare tipi i cui identificatori sono già definiti all'interno dell'unità di compilazione o del corpo dello spazio dei nomi che lo contiene.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. In effetti, i nomi importati da un using_namespace_directive sono nascosti da membri denominati in modo analogo nell'unità di compilazione o nel corpo dello spazio dei nomi contenitore.In effect, names imported by a using_namespace_directive are hidden by similarly named members in the enclosing compilation unit or namespace body. Ad esempio:For example:

namespace N1.N2
{
    class A {}

    class B {}
}

namespace N3
{
    using N1.N2;

    class A {}
}

Qui, all'interno delle dichiarazioni di membro nello N3 spazio dei nomi, A fa riferimento a N3.A anziché a N1.N2.A .Here, within member declarations in the N3 namespace, A refers to N3.A rather than N1.N2.A.

Quando più di uno spazio dei nomi o un tipo importato da using_namespace_directive s o using_static_directive nella stessa unità di compilazione o corpo dello spazio dei nomi contiene tipi con lo stesso nome, i riferimenti a tale nome come type_name vengono considerati ambigui.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. Nell'esempioIn the example

namespace N1
{
    class A {}
}

namespace N2
{
    class A {}
}

namespace N3
{
    using N1;

    using N2;

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

sia N1 che N2 contengono un membro A e, poiché N3 Importa entrambi, A il riferimento in N3 è un errore in fase di compilazione.both N1 and N2 contain a member A, and because N3 imports both, referencing A in N3 is a compile-time error. In questa situazione, il conflitto può essere risolto tramite la qualificazione dei riferimenti a A oppure introducendo un using_alias_directive che sceglie un particolare 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. Ad esempio:For example:

namespace N3
{
    using N1;

    using N2;

    using A = N1.A;

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

Inoltre, quando più di uno spazio dei nomi o un tipo importato da using_namespace_directive s o using_static_directive nella stessa unità di compilazione o corpo dello spazio dei nomi contiene tipi o membri con lo stesso nome, i riferimenti a tale nome come simple_name vengono considerati ambigui.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. Nell'esempioIn 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 contiene un membro di tipo A e C contiene un campo statico A e, poiché N2 Importa entrambi, il riferimento A come simple_name è ambiguo e un errore in fase di compilazione.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.

Analogamente a un using_alias_directive, un using_namespace_directive non fornisce alcun nuovo membro allo spazio di dichiarazione sottostante dell'unità di compilazione o dello spazio dei nomi, ma influiscono solo sull'unità di compilazione o sul corpo dello spazio dei nomi in cui viene visualizzato.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.

Il namespace_name a cui fa riferimento un using_namespace_directive viene risolto in modo analogo al namespace_or_type_name a cui fa riferimento un using_alias_directive.The 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. Pertanto, using_namespace_directive s nella stessa unità di compilazione o corpo dello spazio dei nomi non interessano reciprocamente e possono essere scritti in qualsiasi ordine.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.

Uso di direttive staticheUsing static directives

Un using_static_directive importa i tipi annidati e i membri statici contenuti direttamente in una dichiarazione di tipo nel corpo dello spazio dei nomi o dell'unità di compilazione che lo contiene immediatamente, consentendo l'utilizzo dell'identificatore di ogni membro e tipo senza qualifica.A 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 ';'
    ;

All'interno di dichiarazioni di membri in un'unità di compilazione o in un corpo dello spazio dei nomi che contiene una using_static_directive, è possibile fare riferimento direttamente ai tipi annidati e ai membri statici accessibili (eccetto i metodi di estensione) contenuti direttamente nella dichiarazione del tipo specificato.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. Ad esempio: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(); }
    }
}

In precedenza, all'interno delle dichiarazioni di membri nello N2 spazio dei nomi, i membri statici e i tipi annidati di N1.A sono direttamente disponibili e quindi il metodo N è in grado di fare riferimento sia ai B M membri che di 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.

Un using_static_directive in particolare non importa metodi di estensione direttamente come metodi statici, ma li rende disponibili per la chiamata al metodo di estensione (chiamate al metodo di estensione).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). Nell'esempioIn 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
        }
    }
}

il using_static_directive importa il metodo M di estensione contenuto in N1.A , ma solo come metodo di estensione.the using_static_directive imports the extension method M contained in N1.A, but only as an extension method. Pertanto, il primo riferimento a M nel corpo di B.N genera un errore in fase di compilazione perché nessun membro denominato M è nell'ambito.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.

Un using_static_directive importa solo i membri e i tipi dichiarati direttamente nel tipo specificato, non i membri e i tipi dichiarati nelle classi di base.A using_static_directive only imports members and types declared directly in the given type, not members and types declared in base classes.

TODO: esempioTODO: Example

Le ambiguità tra più using_namespace_directives e using_static_directives sono descritte in utilizzo delle direttive dello spazio dei nomi.Ambiguities between multiple using_namespace_directives and using_static_directives are discussed in Using namespace directives.

Membri dello spazio dei nomiNamespace members

Un namespace_member_declaration è un namespace_declaration (dichiarazioni dello spazio dei nomi) o un type_declaration (dichiarazioni di tipo).A namespace_member_declaration is either a namespace_declaration (Namespace declarations) or a type_declaration (Type declarations).

namespace_member_declaration
    : namespace_declaration
    | type_declaration
    ;

Un'unità di compilazione o un corpo dello spazio dei nomi può contenere namespace_member_declaration s e tali dichiarazioni contribuiscono ai nuovi membri dello spazio di dichiarazione sottostante dell'unità di compilazione o del corpo dello spazio dei nomi che lo contiene.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.

Dichiarazioni di tipiType declarations

Un type_declaration è un class_declaration (dichiarazioni di classe), una struct_declaration (dichiarazioni di struct), un interface_declaration (dichiarazioni di interfaccia), un enum_declaration (dichiarazioni di enumerazione) o un delegate_declaration (dichiarazioni di delegati).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
    ;

Un type_declaration può verificarsi come dichiarazione di primo livello in un'unità di compilazione o come dichiarazione del membro all'interno di uno spazio dei nomi, una classe o uno struct.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.

Quando una dichiarazione di tipo per un tipo T viene eseguita come dichiarazione di primo livello in un'unità di compilazione, il nome completo del tipo appena dichiarato è semplicemente 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. Quando una dichiarazione di tipo per un tipo T si verifica all'interno di uno spazio dei nomi, di una classe o di uno struct, il nome completo del tipo appena dichiarato è N.T , dove N è il nome completo dello spazio dei nomi, della classe o dello struct contenitore.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.

Un tipo dichiarato all'interno di una classe o di uno struct è denominato tipo annidato (tipi annidati).A type declared within a class or struct is called a nested type (Nested types).

I modificatori di accesso consentiti e l'accesso predefinito per una dichiarazione di tipo dipendono dal contesto in cui si verifica la dichiarazione (accessibilità dichiarata):The permitted access modifiers and the default access for a type declaration depend on the context in which the declaration takes place (Declared accessibility):

  • I tipi dichiarati in unità di compilazione o spazi dei nomi possono avere public o internal accedere a.Types declared in compilation units or namespaces can have public or internal access. Il valore predefinito è internal Access.The default is internal access.
  • I tipi dichiarati nelle classi possono avere public accesso,, protected internal protected , internal o private .Types declared in classes can have public, protected internal, protected, internal, or private access. Il valore predefinito è private Access.The default is private access.
  • I tipi dichiarati in struct possono avere public internal accesso, o private .Types declared in structs can have public, internal, or private access. Il valore predefinito è private Access.The default is private access.

Qualificatori di alias dello spazio dei nomiNamespace alias qualifiers

Il qualificatore di alias dello spazio dei nomi :: consente di garantire che le ricerche del nome del tipo non siano interessate dall'introduzione di nuovi tipi e membri.The namespace alias qualifier :: makes it possible to guarantee that type name lookups are unaffected by the introduction of new types and members. Il qualificatore di alias dello spazio dei nomi viene sempre visualizzato tra due identificatori definiti come gli identificatori a sinistra e a destra.The namespace alias qualifier always appears between two identifiers referred to as the left-hand and right-hand identifiers. Diversamente dal . qualificatore regolare, l'identificatore di sinistra del :: qualificatore viene cercato solo come un alias extern o using.Unlike the regular . qualifier, the left-hand identifier of the :: qualifier is looked up only as an extern or using alias.

Un qualified_alias_member viene definito come segue:A qualified_alias_member is defined as follows:

qualified_alias_member
    : identifier '::' identifier type_argument_list?
    ;

Un qualified_alias_member può essere usato come namespace_or_type_name (nomi di spazio dei nomi e di tipo) o come operando sinistro in un member_access (accesso ai membri).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).

Una qualified_alias_member dispone di uno dei due formati seguenti:A qualified_alias_member has one of two forms:

  • N::I<A1, ..., Ak>, dove N e I rappresentano gli identificatori e <A1, ..., Ak> è un elenco di argomenti di tipo.N::I<A1, ..., Ak>, where N and I represent identifiers, and <A1, ..., Ak> is a type argument list. ( K è sempre almeno uno).(K is always at least one.)
  • N::I, dove N e I rappresentano gli identificatori.N::I, where N and I represent identifiers. (In questo caso, K è considerato zero).(In this case, K is considered to be zero.)

Utilizzando questa notazione, il significato di un qualified_alias_member viene determinato nel modo seguente:Using this notation, the meaning of a qualified_alias_member is determined as follows:

  • Se N è l'identificatore global , viene cercato lo spazio dei nomi globale I :If N is the identifier global, then the global namespace is searched for I:

    • Se lo spazio dei nomi globale contiene uno spazio dei nomi denominato  I e K è zero, il qualified_alias_member fa riferimento a tale spazio dei nomi.If the global namespace contains a namespace named I and K is zero, then the qualified_alias_member refers to that namespace.
    • In caso contrario, se lo spazio dei nomi globale contiene un tipo non generico denominato  I e K è zero, il qualified_alias_member fa riferimento a tale tipo.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.
    • In caso contrario, se lo spazio dei nomi globale contiene un tipo denominato  I K   con parametri di tipo, il qualified_alias_member fa riferimento a quel tipo costruito con gli argomenti di tipo specificati.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.
    • In caso contrario, il qualified_alias_member non è definito e si verifica un errore in fase di compilazione.Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.
  • In caso contrario, a partire dalla dichiarazione dello spazio dei nomi (dichiarazioni dello spazio dei nomi) che contiene immediatamente il qualified_alias_member (se presente), continuando con ogni dichiarazione dello spazio dei nomi che lo contiene, e terminando con l'unità di compilazione contenente il qualified_alias_member, i passaggi seguenti vengono valutati fino a quando non si individua un'entità: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:

    • Se la dichiarazione dello spazio dei nomi o l'unità di compilazione contiene un using_alias_directive associato a N un tipo, il qualified_alias_member non è definito e si verifica un errore in fase di compilazione.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.
    • In caso contrario, se la dichiarazione dello spazio dei nomi o l'unità di compilazione contiene un extern_alias_directive o using_alias_directive che associa a N uno spazio dei nomi, quindi:Otherwise, if the namespace declaration or compilation unit contains an extern_alias_directive or using_alias_directive that associates N with a namespace, then:
      • Se lo spazio dei nomi associato a N contiene uno spazio dei nomi denominato  I e K è zero, il qualified_alias_member fa riferimento a tale spazio dei nomi.If the namespace associated with N contains a namespace named I and K is zero, then the qualified_alias_member refers to that namespace.
      • In caso contrario, se lo spazio dei nomi associato a N contiene un tipo non generico denominato  I e K è zero, il qualified_alias_member fa riferimento a tale tipo.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.
      • In caso contrario, se lo spazio dei nomi associato a N contiene un tipo denominato  I con K   parametri di tipo, il qualified_alias_member fa riferimento a quel tipo costruito con gli argomenti di tipo specificati.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.
      • In caso contrario, il qualified_alias_member non è definito e si verifica un errore in fase di compilazione.Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.
  • In caso contrario, il qualified_alias_member non è definito e si verifica un errore in fase di compilazione.Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.

Si noti che l'uso del qualificatore di alias dello spazio dei nomi con un alias che fa riferimento a un tipo causa un errore in fase di compilazione.Note that using the namespace alias qualifier with an alias that references a type causes a compile-time error. Si noti inoltre che se l'identificatore  N è global , la ricerca viene eseguita nello spazio dei nomi globale, anche se è presente un alias using associato a global un tipo o a uno spazio dei nomi.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.

Univocità degli aliasUniqueness of aliases

Ogni unità di compilazione e corpo dello spazio dei nomi ha uno spazio di dichiarazione separato per gli alias extern e l'uso degli alias.Each compilation unit and namespace body has a separate declaration space for extern aliases and using aliases. Pertanto, mentre il nome di un alias extern o l'utilizzo di alias deve essere univoco all'interno del set di alias extern e utilizzando alias dichiarati nell'unità di compilazione o nel corpo dello spazio dei nomi immediatamente contenitore, un alias può avere lo stesso nome di un tipo o di uno spazio dei nomi, purché venga utilizzato solo con il :: qualificatore.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.

Nell'esempioIn 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
    }
}

il nome A ha due possibili significati nel secondo corpo dello spazio dei nomi perché sia la classe A che l'alias using A sono inclusi nell'ambito.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. Per questo motivo, l'utilizzo di A nel nome qualificato A.Stream è ambiguo e causa un errore in fase di compilazione.For this reason, use of A in the qualified name A.Stream is ambiguous and causes a compile-time error to occur. Tuttavia, l'utilizzo di A con il :: qualificatore non è un errore perché A viene cercato solo come alias dello spazio dei nomi.However, use of A with the :: qualifier is not an error because A is looked up only as a namespace alias.