Espacios de nombresNamespaces

Programas de C# se organizan mediante espacios de nombres.C# programs are organized using namespaces. Los espacios de nombres se utilizan como un sistema de organización "interno" para un programa y como un sistema de organización "external": una forma de presentar los elementos de programa que se exponen a otros programas.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.

Las directivas using (directivas Using) se proporcionan para facilitar el uso de espacios de nombres.Using directives (Using directives) are provided to facilitate the use of namespaces.

Unidades de compilaciónCompilation units

Un compilation_unit define la estructura general de un archivo de origen.A compilation_unit defines the overall structure of a source file. Una unidad de compilación se compone de cero o más using_directives seguido de cero o más global_attributes seguido de cero o más namespace_member_declarations .A compilation unit consists of zero or more using_directives followed by zero or more global_attributes followed by zero or more namespace_member_declarations.

compilation_unit
    : extern_alias_directive* using_directive* global_attributes? namespace_member_declaration*
    ;

Un programa de C# consta de uno o más unidades de compilación, contenidos todos ellos en un archivo de código fuente independiente.A C# program consists of one or more compilation units, each contained in a separate source file. Cuando se compila un programa de C#, todas las unidades de compilación se procesan juntos.When a C# program is compiled, all of the compilation units are processed together. Por lo tanto, unidades de compilación pueden depender entre sí, posiblemente, de manera circular.Thus, compilation units can depend on each other, possibly in a circular fashion.

El using_directives una unidad de compilación pueden afectar a la global_attributes y namespace_member_declarations de esa unidad de compilación, pero no tienen ningún efecto otras unidades de compilación.The using_directives of a compilation unit affect the global_attributes and namespace_member_declarations of that compilation unit, but have no effect on other compilation units.

El global_attributes (atributos) de una unidad de compilación permiten la especificación de atributos para el ensamblado de destino y el módulo.The global_attributes (Attributes) of a compilation unit permit the specification of attributes for the target assembly and module. Ensamblados y módulos actúan como contenedores físicos de tipos.Assemblies and modules act as physical containers for types. Un ensamblado puede constar de varios módulos separados físicamente.An assembly may consist of several physically separate modules.

El namespace_member_declarations de cada unidad de compilación de un programa contribuyen a los miembros a un espacio de declaración única denominado el espacio de nombres global.The namespace_member_declarations of each compilation unit of a program contribute members to a single declaration space called the global namespace. Por ejemplo:For example:

Archivo A.cs:File A.cs:

class A {}

Archivo B.cs:File B.cs:

class B {}

Las dos unidades de compilación contribuyen al espacio de nombres global único, en este caso declarar dos clases con los nombres completos A y 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. Dado que las dos unidades de compilación contribuyen al mismo espacio de declaración, habría sido un error si cada una contiene una declaración de un miembro con el mismo nombre.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.

Declaraciones de espacios de nombresNamespace declarations

Un namespace_declaration consta de la palabra clave namespace, seguido de un espacio de nombres y un cuerpo, seguido opcionalmente por un punto y coma.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 puede producirse como una declaración de nivel superior en un compilation_unit o como una declaración de miembro dentro de otra 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. Cuando un namespace_declaration se produce como una declaración de nivel superior en un compilation_unit, el espacio de nombres se convierte en miembro del espacio de nombres global.When a namespace_declaration occurs as a top-level declaration in a compilation_unit, the namespace becomes a member of the global namespace. Cuando un namespace_declaration se produce dentro de otra namespace_declaration, el espacio de nombres interno se convierte en un miembro del espacio de nombres exterior.When a namespace_declaration occurs within another namespace_declaration, the inner namespace becomes a member of the outer namespace. En cualquier caso, el nombre de un espacio de nombres debe ser único dentro del espacio de nombres contenedor.In either case, the name of a namespace must be unique within the containing namespace.

Los espacios de nombres son implícitamente public y la declaración de un espacio de nombres no puede incluir modificadores de acceso.Namespaces are implicitly public and the declaration of a namespace cannot include any access modifiers.

Dentro de un namespace_body, opcional using_directives importar los nombres de otros espacios de nombres, tipos y miembros, lo que permite hacer referencia a él directamente en lugar de a través de los nombres completos.Within a namespace_body, the optional using_directives import the names of other namespaces, types and members, allowing them to be referenced directly instead of through qualified names. El elemento opcional namespace_member_declarations contribuyen a los miembros del espacio de declaración de espacio de nombres.The optional namespace_member_declarations contribute members to the declaration space of the namespace. Tenga en cuenta que todos los using_directives deben aparecer antes que cualquier declaración de miembro.Note that all using_directives must appear before any member declarations.

El qualified_identifier de un namespace_declaration puede ser un identificador único o una secuencia de identificadores separados por "." tokens.The qualified_identifier of a namespace_declaration may be a single identifier or a sequence of identifiers separated by "." tokens. La segunda forma permite que un programa para definir un espacio de nombres anidado sin anidar léxicamente varias declaraciones de espacio de nombres.The latter form permits a program to define a nested namespace without lexically nesting several namespace declarations. Por ejemplo,For example,

namespace N1.N2
{
    class A {}

    class B {}
}

es semánticamente equivalente ais semantically equivalent to

namespace N1
{
    namespace N2
    {
        class A {}

        class B {}
    }
}

Los espacios de nombres son abiertas y dos declaraciones de espacio de nombres con el mismo nombre completo contribuyen al mismo espacio de declaración (declaraciones).Namespaces are open-ended, and two namespace declarations with the same fully qualified name contribute to the same declaration space (Declarations). En el ejemploIn the example

namespace N1.N2
{
    class A {}
}

namespace N1.N2
{
    class B {}
}

Las dos declaraciones de espacio de nombres anteriores contribuyen al mismo espacio de declaración, en este caso declarar dos clases con los nombres completos N1.N2.A y 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. Dado que las dos declaraciones contribuyen al mismo espacio de declaración, habría sido un error si cada uno contiene una declaración de un miembro con el mismo nombre.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 externosExtern aliases

Un extern_alias_directive presenta un identificador que actúa como un alias para un espacio de nombres.An extern_alias_directive introduces an identifier that serves as an alias for a namespace. La especificación del espacio de nombres con alias es externa al código fuente del programa y se aplica también a los espacios de nombres anidados del espacio de nombres 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 ';'
    ;

El ámbito de un extern_alias_directive se extiende a través de la using_directives, global_attributes y namespace_member_declarations de su cuerpo contenedor inmediato de espacio de nombres o la unidad de compilación.The scope of an extern_alias_directive extends over the using_directives, global_attributes and namespace_member_declarations of its immediately containing compilation unit or namespace body.

Dentro de un cuerpo de espacio de nombres o la unidad de compilación que contiene un extern_alias_directive, el identificador definido por el extern_alias_directive puede usarse para hacer referencia el espacio de nombres 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. Es un error en tiempo de compilación para la identificador debe ser la palabra global.It is a compile-time error for the identifier to be the word global.

Un extern_alias_directive ofrece un alias dentro de un cuerpo de espacio de nombres o la unidad de compilación concreta, pero no aporta ningún miembro nuevo al espacio de declaración subyacente.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. En otras palabras, un extern_alias_directive no es transitiva, pero, en su lugar, sólo afecta a la compilación unidad o el espacio de nombres de cuerpo en el que se produce.In other words, an extern_alias_directive is not transitive, but, rather, affects only the compilation unit or namespace body in which it occurs.

El programa siguiente declara y usa dos alias externos, X y Y, cada uno de los que representan la raíz de una jerarquía de espacio de nombres distinto: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;
}

El programa declara la existencia de la extern alias X y Y, pero las definiciones actuales de los alias son externas al programa.The program declares the existence of the extern aliases X and Y, but the actual definitions of the aliases are external to the program. Con el mismo nombre N.B ahora se pueden hacer referencia a las clases como X.N.B y Y.N.B, o bien, mediante el calificador de alias de espacio de nombres, X::N.B y 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. Se produce un error si un programa declara un alias externo para el que no se proporciona ninguna definición externa.An error occurs if a program declares an extern alias for which no external definition is provided.

directivas usingUsing directives

Directivas using facilitan el uso de espacios de nombres y tipos definidos en otros espacios de nombres.Using directives facilitate the use of namespaces and types defined in other namespaces. Mediante el impacto de las directivas en el proceso de resolución de nombres de namespace_or_type_names (Namespace y nombres de tipo) y simple_names (nombres simples ), pero a diferencia de las declaraciones, las directivas using no contribuyen nuevos miembros a los espacios de declaración subyacentes de las unidades de compilación o espacios de nombres en el que se usan.Using directives impact the name resolution process of namespace_or_type_names (Namespace and type names) and simple_names (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 (directivas Using alias) introduce un alias para un espacio de nombres o tipo.A using_alias_directive (Using alias directives) introduces an alias for a namespace or type.

Un using_namespace_directive (directivas de espacio de nombres Using) importa los miembros de tipo de un espacio de nombres.A using_namespace_directive (Using namespace directives) imports the type members of a namespace.

Un using_static_directive (directivas Using static) importa los tipos anidados y miembros estáticos de un tipo.A using_static_directive (Using static directives) imports the nested types and static members of a type.

El ámbito de un using_directive se extiende a través de la namespace_member_declarations de su cuerpo contenedor inmediato de espacio de nombres o la unidad de compilación.The scope of a using_directive extends over the namespace_member_declarations of its immediately containing compilation unit or namespace body. El ámbito de un using_directive específicamente no incluye su interlocutor using_directives.The scope of a using_directive specifically does not include its peer using_directives. Por lo tanto, del mismo nivel using_directives no afectan a entre sí y el orden en el que se escriben es insignificante.Thus, peer using_directives do not affect each other, and the order in which they are written is insignificant.

Directivas de alias usingUsing alias directives

Un using_alias_directive presenta un identificador que actúa como un alias para un espacio de nombres o tipo dentro del cuerpo de espacio de nombres o la unidad de compilación inmediatamente envolvente.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 ';'
    ;

Dentro de las declaraciones de miembros en un cuerpo de espacio de nombres o la unidad de compilación que contiene un using_alias_directive, el identificador definido por el using_alias_directive puede usarse para hacer referencia a la determinada espacio de nombres o tipo.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. Por ejemplo:For example:

namespace N1.N2
{
    class A {}
}

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

    class B: A {}
}

Anterior, dentro de las declaraciones de miembros en el N3 espacio de nombres, A es un alias para N1.N2.Ay, por tanto, la clase N3.B se deriva de la clase 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. El mismo efecto que puede obtenerse mediante la creación de un alias R para N1.N2 y, a continuación, hacer referencia 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 {}
}

El identificador de un using_alias_directive debe ser único dentro del espacio de declaración de la unidad de compilación o espacio de nombres que contiene inmediatamente la 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. Por ejemplo:For example:

namespace N3
{
    class A {}
}

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

Anterior, N3 ya contiene un miembro A, por lo que es un error en tiempo de compilación para un using_alias_directive utilice ese identificador.Above, N3 already contains a member A, so it is a compile-time error for a using_alias_directive to use that identifier. Del mismo modo, es un error en tiempo de compilación para dos o más using_alias_directives en el cuerpo mismo de espacio de nombres o la unidad de compilación para declarar los alias con el mismo nombre.Likewise, it is a compile-time error for two or more using_alias_directives in the same compilation unit or namespace body to declare aliases by the same name.

Un using_alias_directive ofrece un alias dentro de un cuerpo de espacio de nombres o la unidad de compilación concreta, pero no aporta ningún miembro nuevo al espacio de declaración subyacente.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. En otras palabras, un using_alias_directive no es transitiva, pero en su lugar sólo afecta a la compilación unidad o el espacio de nombres de cuerpo en el que se produce.In other words, a using_alias_directive is not transitive but rather affects only the compilation unit or namespace body in which it occurs. En el ejemploIn the example

namespace N3
{
    using R = N1.N2;
}

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

el ámbito de la using_alias_directive que presenta R sólo se extiende a las declaraciones de miembros en el cuerpo de espacio de nombres que lo contiene, por lo que R es desconocido en la segunda declaración de espacio de nombres.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. Sin embargo, colocar el using_alias_directive en la compilación que lo contiene unidad hace que el alias para que estén disponibles en ambas declaraciones de espacio de nombres: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 {}
}

Al igual que los miembros normales, los nombres introducen por using_alias_directives se ocultan los miembros con el mismo nombre en ámbitos anidados.Just like regular members, names introduced by using_alias_directives are hidden by similarly named members in nested scopes. En el ejemploIn the example

using R = N1.N2;

namespace N3
{
    class R {}

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

la referencia a R.A en la declaración de B genera un error de tiempo de compilación porque R hace referencia a N3.R, no 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.

El orden en que using_alias_directives se escriben no tiene ninguna importancia y la resolución de la namespace_or_type_name hace referencia a él un using_alias_directiveno se ve afectado por la using_alias_directive propio o por otro using_directives en el cuerpo de espacio de nombres o la unidad de compilación contenedor inmediato.The order in which using_alias_directives 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_directives in the immediately containing compilation unit or namespace body. En otras palabras, el namespace_or_type_name de un using_alias_directive se resuelve como si el cuerpo de espacio de nombres o la unidad de compilación contenedor inmediato no tuviese using_directives.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_directives. Un using_alias_directive pero puede ser afectado por extern_alias_directives en el cuerpo de espacio de nombres o la unidad de compilación contenedor inmediato.A using_alias_directive may however be affected by extern_alias_directives in the immediately containing compilation unit or namespace body. En el ejemploIn 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
}

la última using_alias_directive da como resultado un error en tiempo de compilación porque no se ve afectado por la primera 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. La primera using_alias_directive no produce un error desde el ámbito de lo alias externo E incluye la 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 puede crear un alias para cualquier espacio de nombres o tipo, incluido el espacio de nombres en el que aparece y cualquier espacio de nombres o tipo anidado dentro de ese espacio de nombres.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.

Acceso a un tipo o espacio de nombres a través de un alias produce exactamente el mismo resultado que obtener acceso a dicho espacio de nombres o tipo mediante su nombre declarado.Accessing a namespace or type through an alias yields exactly the same result as accessing that namespace or type through its declared name. Por ejemplo, dadaFor 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
    }
}

los nombres N1.N2.A, R1.N2.A, y R2.A son equivalentes y todos hacen referencia a la clase cuyo nombre completo es 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.

El uso de alias puede nombre de un tipo construido cerrado, pero no el nombre de una declaración de tipo genérico sin enlazar sin proporcionar argumentos de tipo.Using aliases can name a closed constructed type, but cannot name an unbound generic type declaration without supplying type arguments. Por ejemplo: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
}

Espacio de nombres directivas usingUsing namespace directives

Un using_namespace_directive importa los tipos contenidos en un espacio de nombres en la compilación cuerpo inmediatamente envolvente unidad o el espacio de nombres, lo que permite el identificador de cada tipo que se puede usar sin calificación.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 ';'
    ;

Dentro de las declaraciones de miembros en un cuerpo de espacio de nombres o la unidad de compilación que contiene un using_namespace_directive, pueden hacer referencia directamente a los tipos contenidos en el espacio de nombres especificado.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. Por ejemplo:For example:

namespace N1.N2
{
    class A {}
}

namespace N3
{
    using N1.N2;

    class B: A {}
}

Anterior, dentro de las declaraciones de miembros en el N3 espacio de nombres, los miembros de tipo de N1.N2 están directamente disponibles y, por tanto, la clase N3.B se deriva de la clase 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 los tipos contenidos en el espacio de nombres especificado, pero no importa específicamente los espacios de nombres anidados.A using_namespace_directive imports the types contained in the given namespace, but specifically does not import nested namespaces. En el ejemploIn the example

namespace N1.N2
{
    class A {}
}

namespace N3
{
    using N1;

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

el using_namespace_directive importa los tipos contenidos en N1, pero no los espacios de nombres anidados en N1.the using_namespace_directive imports the types contained in N1, but not the namespaces nested in N1. Por lo tanto, la referencia a N2.A en la declaración de B da como resultado un error en tiempo de compilación porque ningún miembro llamado N2 están en el ámbito.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 diferencia de un using_alias_directive, un using_namespace_directive puede importar tipos cuyos identificadores ya están definidos dentro del cuerpo de espacio de nombres o la unidad de compilación envolvente.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. De hecho, los nombres importan por un using_namespace_directive están ocultos por miembros con el mismo nombre en el cuerpo de espacio de nombres o la unidad de compilación envolvente.In effect, names imported by a using_namespace_directive are hidden by similarly named members in the enclosing compilation unit or namespace body. Por ejemplo:For example:

namespace N1.N2
{
    class A {}

    class B {}
}

namespace N3
{
    using N1.N2;

    class A {}
}

Aquí, en las declaraciones de miembros en el N3 espacio de nombres, A hace referencia a N3.A lugar N1.N2.A.Here, within member declarations in the N3 namespace, A refers to N3.A rather than N1.N2.A.

Cuando más de un espacio de nombres o tipo importado por using_namespace_directives o using_static_directives en el mismo cuerpo de espacio de nombres o la unidad de compilación contiene tipos para el mismo nombre, las referencias a ese nombre como un type_name se consideran ambiguos.When more than one namespace or type imported by using_namespace_directives or using_static_directives 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. En el ejemploIn the example

namespace N1
{
    class A {}
}

namespace N2
{
    class A {}
}

namespace N3
{
    using N1;

    using N2;

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

ambos N1 y N2 contienen un miembro Ay porque N3 importa ambos, que hacen referencia a A en N3 es un error en tiempo de compilación.both N1 and N2 contain a member A, and because N3 imports both, referencing A in N3 is a compile-time error. En esta situación, el conflicto se puede resolver mediante la calificación de referencias a A, o bien introduciendo un using_alias_directive que toma un determinado 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. Por ejemplo:For example:

namespace N3
{
    using N1;

    using N2;

    using A = N1.A;

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

Además, cuando más de un espacio de nombres o tipo importado por using_namespace_directives o using_static_directives en el mismo cuerpo de espacio de nombres o la unidad de compilación contiene tipos o miembros mediante el mismo nombre, las referencias a ese nombre como un simple_name se consideran ambiguos.Furthermore, when more than one namespace or type imported by using_namespace_directives or using_static_directives 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. En el ejemploIn 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 miembro de tipo A, y C contiene un campo estático Ay porque N2 importa ambos, que hacen referencia a A como un simple_name es ambiguo y un tiempo de compilación error.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.

Al igual que un using_alias_directive, un using_namespace_directive no contribuye con ningún miembro nuevo al espacio de declaración subyacente de la unidad de compilación o espacio de nombres, sino que afecta a solo el compilación cuerpo unidad o el espacio de nombres en el que aparece.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.

El namespace_name hace referencia a él un using_namespace_directive se resuelve en la misma manera que el namespace_or_type_name hace referencia a él 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. Por lo tanto, using_namespace_directives en el mismo cuerpo de espacio de nombres o la unidad de compilación no afectan a entre sí y pueden escribirse en cualquier orden.Thus, using_namespace_directives in the same compilation unit or namespace body do not affect each other and can be written in any order.

Directivas using staticUsing static directives

Un using_static_directive importa los tipos anidados y miembros estáticos contenidos directamente en una declaración de tipo en el cuerpo inmediatamente envolvente compilación unidad o el espacio de nombres, lo que permite el identificador de cada miembro y tipo que utilizar sin calificación.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 ';'
    ;

Dentro de las declaraciones de miembros en un cuerpo de espacio de nombres o la unidad de compilación que contiene un using_static_directive, el accesible anidar tipos y miembros estáticos (excepto los métodos de extensión) contenidos directamente en la declaración de la tipo especificado se puede hacer referencia directamente.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. Por ejemplo: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(); }
    }
}

Anterior, dentro de las declaraciones de miembros en el N2 espacio de nombres, los miembros estáticos y los tipos anidados de N1.A están directamente disponibles y, por tanto, el método N es capaz de hacer referencia tanto la B y M los miembros de 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 específicamente no importa los métodos de extensión directamente como métodos estáticos, pero hace que estén disponibles para la invocación del método de extensión (las invocaciones de método de extensión).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). En el ejemploIn 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
        }
    }
}

el using_static_directive importa el método de extensión M contenidos en N1.A, sino únicamente como un método de extensión.the using_static_directive imports the extension method M contained in N1.A, but only as an extension method. Por lo tanto, la primera referencia a M en el cuerpo de B.N da como resultado un error en tiempo de compilación porque ningún miembro llamado M están en el ámbito.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 sólo importa los miembros y tipos declarados directamente en el tipo especificado, no a los tipos y miembros declaran en las clases 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: EjemploTODO: Example

Las ambigüedades entre varias using_namespace_directives y using_static_directives se tratan en mediante directivas de espacio de nombres.Ambiguities between multiple using_namespace_directives and using_static_directives are discussed in Using namespace directives.

Miembros de NamespaceNamespace members

Un namespace_member_declaration sea un namespace_declaration (declaraciones Namespace) o un type_declaration () Declaraciones de 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
    ;

Una unidad de compilación o un cuerpo de espacio de nombres puede contener namespace_member_declarations y dichas declaraciones contribuyen nuevos miembros al espacio de declaración subyacente del cuerpo de espacio de nombres o la unidad de compilación que contiene.A compilation unit or a namespace body can contain namespace_member_declarations, and such declarations contribute new members to the underlying declaration space of the containing compilation unit or namespace body.

Declaraciones de tiposType declarations

Un type_declaration es un class_declaration (declaraciones de clase), un struct_declaration (Struct las declaraciones), un interface_declaration (declaraciones de interfaz), un enum_declaration (Enum las declaraciones), o un delegate_declaration (declaraciones de delegado).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 puede ocurrir como una declaración de nivel superior en una unidad de compilación o como una declaración de miembro dentro de un espacio de nombres, clase o 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.

Cuando una declaración de tipos para un tipo T se produce como una declaración de nivel superior en una unidad de compilación, el nombre completo del nuevo tipo declarado es simplemente 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. Cuando una declaración de tipos para un tipo T se produce dentro de un espacio de nombres, clase o struct, el nombre completo del nuevo tipo declarado es N.T, donde N es el nombre completo del espacio de nombres, clase o estructura contenedora.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 declarado dentro de una clase o struct se denomina tipo anidado (tipos anidados).A type declared within a class or struct is called a nested type (Nested types).

Los modificadores de acceso permitido y el acceso predeterminado para una declaración de tipo dependen del contexto en el que tiene lugar la declaración (accesibilidad declarada):The permitted access modifiers and the default access for a type declaration depend on the context in which the declaration takes place (Declared accessibility):

  • Pueden tener tipos declarados en unidades de compilación o espacios de nombres public o internal acceso.Types declared in compilation units or namespaces can have public or internal access. El valor predeterminado es internal acceso.The default is internal access.
  • Los tipos declarados en las clases pueden tener public, protected internal, protected, internal, o private acceso.Types declared in classes can have public, protected internal, protected, internal, or private access. El valor predeterminado es private acceso.The default is private access.
  • Los tipos declarados en estructuras pueden tener public, internal, o private acceso.Types declared in structs can have public, internal, or private access. El valor predeterminado es private acceso.The default is private access.

Calificadores de alias NamespaceNamespace alias qualifiers

El calificador de alias de espacio de nombres :: hace posible garantizar que las búsquedas de nombres de tipo no se ven afectadas por la introducción de nuevos tipos y miembros.The namespace alias qualifier :: makes it possible to guarantee that type name lookups are unaffected by the introduction of new types and members. El calificador de alias de espacio de nombres siempre aparece entre dos identificadores que se conoce como los identificadores de la izquierda y derecha.The namespace alias qualifier always appears between two identifiers referred to as the left-hand and right-hand identifiers. A diferencia de las tarifas . calificador, el identificador izquierdo de la :: calificador se busca sólo como un alias de using o extern.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 se define como sigue:A qualified_alias_member is defined as follows:

qualified_alias_member
    : identifier '::' identifier type_argument_list?
    ;

Un qualified_alias_member puede usarse como un namespace_or_type_name (Namespace y nombres de tipo) o como el operando izquierdo de un member_access (Acceso a miembros).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).

Un qualified_alias_member tiene uno de dos formas:A qualified_alias_member has one of two forms:

  • N::I<A1, ..., Ak>, donde N y I representan identificadores, y <A1, ..., Ak> es una lista de argumentos de tipo.N::I<A1, ..., Ak>, where N and I represent identifiers, and <A1, ..., Ak> is a type argument list. (K siempre es al menos uno.)(K is always at least one.)
  • N::I, donde N y I representan identificadores.N::I, where N and I represent identifiers. (En este caso, K se considera igual a cero.)(In this case, K is considered to be zero.)

Usa esta notación, el significado de un qualified_alias_member se determina como sigue:Using this notation, the meaning of a qualified_alias_member is determined as follows:

  • Si N es el identificador global, a continuación, se busca el espacio de nombres global I:If N is the identifier global, then the global namespace is searched for I:

    • Si el espacio de nombres global contiene un espacio de nombres denominado I y K es cero, el qualified_alias_member hace referencia a ese espacio de nombres.If the global namespace contains a namespace named I and K is zero, then the qualified_alias_member refers to that namespace.
    • En caso contrario, si el espacio de nombres global contiene un tipo no genérico denominado I y K es cero, el qualified_alias_member hace referencia a ese 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.
    • En caso contrario, si el espacio de nombres global contiene un tipo denominado I cuya K  parámetros de tipo, el qualified_alias_member hace referencia a ese tipo construido con los argumentos de tipo especificado.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.
    • En caso contrario, el qualified_alias_member es no definido y se produce un error de tiempo de compilación.Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.
  • En caso contrario, empezando con la declaración de espacio de nombres (declaraciones Namespace) inmediatamente que contiene el qualified_alias_member (si existe), continuando con cada declaración de espacio de nombres envolvente (si existe) y termina con la unidad de compilación que contiene el qualified_alias_member, se evalúan los pasos siguientes hasta que se encuentra una entidad: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:

    • Si la unidad de compilación o de declaración de espacio de nombres contiene un using_alias_directive que asocia N con un tipo, el qualified_alias_member no está definido y un tiempo de compilación se produce un error.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.
    • En caso contrario, si la unidad de compilación o de declaración de espacio de nombres contiene un extern_alias_directive o using_alias_directive que asocia N con un espacio de nombres, a continuación:Otherwise, if the namespace declaration or compilation unit contains an extern_alias_directive or using_alias_directive that associates N with a namespace, then:
      • Si el espacio de nombres asociado N contiene un espacio de nombres denominado I y K es cero, el qualified_alias_member hace referencia a ese espacio de nombres.If the namespace associated with N contains a namespace named I and K is zero, then the qualified_alias_member refers to that namespace.
      • En caso contrario, si el espacio de nombres asociado N contiene un tipo no genérico denominado I y K es cero, el qualified_alias_member hace referencia a ese 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.
      • En caso contrario, si el espacio de nombres asociado N contiene un tipo denominado I cuya K  parámetros de tipo, el qualified_alias_member hace referencia a dicho tipo construido con los argumentos de tipo especificado.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.
      • En caso contrario, el qualified_alias_member es no definido y se produce un error de tiempo de compilación.Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.
  • En caso contrario, el qualified_alias_member es no definido y se produce un error de tiempo de compilación.Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.

Tenga en cuenta que uso el calificador de alias de espacio de nombres con un alias que hace referencia a un tipo produce un error de tiempo de compilación.Note that using the namespace alias qualifier with an alias that references a type causes a compile-time error. Observe también que si el identificador N es global, a continuación, se realiza una búsqueda en el espacio de nombres global, incluso si hay un alias using que asocia global con un tipo o espacio de nombres.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.

Unicidad de los aliasUniqueness of aliases

Cada cuerpo de unidad y el espacio de nombres de compilación tiene un espacio de declaración independiente para los alias externos y el uso de alias.Each compilation unit and namespace body has a separate declaration space for extern aliases and using aliases. Por lo tanto, aunque el nombre de alias using o un alias externo debe ser único dentro del conjunto de alias externos y el uso de alias declarados en el cuerpo de espacio de nombres o la unidad de compilación contenedor inmediato, un alias puede tener el mismo nombre que un tipo o espacio de nombres siempre y cuando t solo se usa con el :: calificador.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.

En el ejemploIn 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
    }
}

el nombre A tiene dos significados posibles en el cuerpo de espacio de nombres de segundo, porque la clase A y el uso de alias A están en el ámbito.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. Para ello, el uso de A en el nombre completo A.Stream es ambigua y produce un error de tiempo de compilación que se produzca.For this reason, use of A in the qualified name A.Stream is ambiguous and causes a compile-time error to occur. Sin embargo, usar de A con el :: calificador no es un error porque A se busca sólo como un alias de espacio de nombres.However, use of A with the :: qualifier is not an error because A is looked up only as a namespace alias.