Espacios de nombresNamespaces

Los programas de C# se organizan mediante espacios de nombres.C# programs are organized using namespaces. Los espacios de nombres se usan como un sistema de organización "interno" para un programa, y como un sistema de organización "externo", una manera 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 global de un archivo de código fuente.A compilation_unit defines the overall structure of a source file. Una unidad de compilación consta de cero o más using_directive s seguidos de cero o más global_attributes seguidos de cero o más 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 programa de C# se compone de una o varias unidades de compilación, cada una de ellas 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 juntas.When a C# program is compiled, all of the compilation units are processed together. Por lo tanto, las 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.

Los using_directive de una unidad de compilación afectan al global_attributes y namespace_member_declaration s de esa unidad de compilación, pero no tienen ningún efecto en otras unidades de compilación.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.

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

El namespace_member_declaration s de cada unidad de compilación de un programa contribuye a los miembros a un solo espacio de declaración denominado espacio de nombres global.The namespace_member_declaration s 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, se declaran 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 de ellas contenía 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 nombre de espacio de nombres y un cuerpo, seguido opcionalmente de 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 se produce un namespace_declaration como una declaración de nivel superior en una compilation_unit, el espacio de nombres se convierte en un 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 se produce un namespace_declaration dentro de otro 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 que lo contiene.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, los using_directive s opcionales importan los nombres de otros espacios de nombres, tipos y miembros, lo que permite hacer referencia a ellos directamente en lugar de a través de nombres completos.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. El namespace_member_declaration s opcional contribuye al espacio de declaración del espacio de nombres.The optional namespace_member_declaration s contribute members to the declaration space of the namespace. Tenga en cuenta que todos los using_directive s deben aparecer antes de cualquier declaración de miembro.Note that all using_directive s 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. El último formulario permite a un programa definir un espacio de nombres anidado sin anidar léxicamente varias declaraciones de espacios 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 están abiertos y dos declaraciones de espacios 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, se declaran 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, se habría producido un error si cada una de ellas contenía 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

Una extern_alias_directive introduce 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 por las using_directive s, global_attributes y namespace_member_declaration s de su unidad de compilación o cuerpo de espacio de nombres que contiene inmediatamente.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.

Dentro de una unidad de compilación o un cuerpo de espacio de nombres que contiene un extern_alias_directive, el identificador introducido por el extern_alias_directive se puede usar para hacer referencia al 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. Se trata de un error en tiempo de compilación para que el identificador sea la palabra global .It is a compile-time error for the identifier to be the word global.

Un extern_alias_directive hace que un alias esté disponible dentro de una unidad de compilación o un cuerpo de espacio de nombres concretos, 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, una extern_alias_directive no es transitiva, sino que afecta solo a la unidad de compilación o al cuerpo del espacio de nombres 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 extern, X y Y , cada uno de los cuales representa la raíz de una jerarquía de espacios de nombres distinta: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 los alias extern X y Y , pero las definiciones reales 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. N.BAhora se puede hacer referencia a las clases con el mismo nombre como X.N.B y Y.N.B , o mediante el calificador de alias del 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 extern 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

*El uso de directivas _ facilita 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. Las directivas de uso afectan al proceso de resolución de nombres de _namespace_or_type_name * s (nombres de espacio de nombres y tipos) y simple_name s (nombres simples), pero a diferencia de las declaraciones, las directivas Using no aportan nuevos miembros a los espacios de declaración subyacentes de las unidades de compilación o los espacios de nombres en los que se utilizan.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 (mediante directivas de alias) introduce un alias para un espacio de nombres o un tipo.A using_alias_directive (Using alias directives) introduces an alias for a namespace or type.

Un using_namespace_directive (mediante directivas de espacio de nombres) 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 (mediante directivas estáticas) importa los tipos anidados y los 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 una using_directive amplía el namespace_member_declaration s de la unidad de compilación o el cuerpo del espacio de nombres que contiene inmediatamente.The scope of a using_directive extends over the namespace_member_declaration s of its immediately containing compilation unit or namespace body. El ámbito de un using_directive no incluye específicamente sus using_directive s del mismo nivel.The scope of a using_directive specifically does not include its peer using_directive s. Por lo tanto, los using_directive del mismo nivel no afectan entre sí y el orden en el que se escriben es insignificante.Thus, peer using_directive s do not affect each other, and the order in which they are written is insignificant.

Usar directivas de aliasUsing alias directives

Una using_alias_directive introduce un identificador que actúa como alias para un espacio de nombres o tipo dentro de la unidad de compilación o el cuerpo del espacio de nombres que se encuentra inmediatamente.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 de una unidad de compilación o un cuerpo de espacio de nombres que contiene un using_alias_directive, el identificador introducido por el using_alias_directive se puede usar para hacer referencia al espacio de nombres o tipo especificado.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 {}
}

Anteriormente, dentro de las declaraciones de miembros del N3 espacio de nombres, A es un alias para N1.N2.A y, por lo tanto, la clase N3.B 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. Se puede obtener el mismo efecto si se crea un alias R para N1.N2 y, a continuación, se hace 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 en el espacio de declaración de la unidad de compilación o espacio de nombres que contiene inmediatamente el 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
}

Anteriormente, N3 ya contiene un miembro A , por lo que es un error en tiempo de compilación para que un using_alias_directive use 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, se trata de un error en tiempo de compilación para dos o más using_alias_directive s en la misma unidad de compilación o cuerpo del espacio de nombres para declarar alias con el mismo nombre.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 hace que un alias esté disponible dentro de una unidad de compilación o un cuerpo de espacio de nombres concretos, 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, una using_alias_directive no es transitiva sino que solo afecta a la unidad de compilación o al cuerpo del espacio de nombres 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 introduce R solo se extiende a las declaraciones de miembros en el cuerpo del espacio de nombres en el que está contenido, por lo que R se desconoce 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 unidad de compilación contenedora hace que el alias esté disponible 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 introducidos por using_alias_directive s están ocultos por miembros con el mismo nombre en ámbitos anidados.Just like regular members, names introduced by using_alias_directive s 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 produce un error en tiempo de compilación porque R hace referencia a N3.R , no 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.

El orden en el que se escriben using_alias_directive s no tiene importancia y la resolución de los namespace_or_type_name a los que hace referencia un using_alias_directive no se ve afectada por la using_alias_directive misma o por otras using_directive en la unidad de compilación o el cuerpo del espacio de nombres que contiene inmediatamente.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. En otras palabras, el namespace_or_type_name de una using_alias_directive se resuelve como si la unidad de compilación o el cuerpo del espacio de nombres que contiene no tengan 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. No obstante, un using_alias_directive puede verse afectado por extern_alias_directive s en la unidad de compilación o el cuerpo del espacio de nombres que contiene inmediatamente.A using_alias_directive may however be affected by extern_alias_directive s 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
}

el último using_alias_directive produce 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, puesto que el ámbito del alias extern E incluye el 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.

El acceso a un espacio de nombres o a un tipo a través de un alias produce exactamente el mismo resultado que el acceso a ese espacio de nombres o el tipo a través de 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, dadoFor 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 asignar un nombre a un tipo construido cerrado, pero no puede asignar un nombre a 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
}

Usar directivas de espacio de nombresUsing namespace directives

Un using_namespace_directive importa los tipos contenidos en un espacio de nombres en la unidad de compilación o el cuerpo del espacio de nombres que se encuentran inmediatamente, lo que permite usar el identificador de cada tipo 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 de una unidad de compilación o un cuerpo de espacio de nombres que contiene un using_namespace_directive, se puede hacer referencia a los tipos contenidos en el espacio de nombres especificado directamente.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 {}
}

Anteriormente, dentro de las declaraciones de miembros del N3 espacio de nombres, los miembros de tipo de N1.N2 están directamente disponibles y, por lo tanto, la clase N3.B 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 específicamente no importa 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 incluidos 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 genera un error en tiempo de compilación porque ningún miembro denominado N2 está 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 de la unidad de compilación o el cuerpo del espacio de nombres 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. En efecto, los nombres importados por un using_namespace_directive están ocultos por miembros con el mismo nombre en la unidad de compilación o el cuerpo del espacio de nombres 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í, dentro de las declaraciones de miembro del N3 espacio de nombres, A hace referencia a en N3.A lugar de a 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_directive s o using_static_directive s en la misma unidad de compilación o cuerpo de espacio de nombres contienen tipos con el mismo nombre, las referencias a ese nombre como un type_name se consideran ambiguas.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. 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
}

N1y N2 contienen un miembro A , y dado que las N3 importaciones, 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 a través de la calificación de referencias a A o mediante la introducción de una using_alias_directive que elige 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_directive s o using_static_directive s en la misma unidad de compilación o cuerpo de espacio de nombres contienen tipos o miembros con el mismo nombre, las referencias a ese nombre como un simple_name se consideran ambiguas.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. 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 A , y dado N2 que importa ambos, hacer referencia A a como simple_name es ambiguo y un error en tiempo de compilación.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 una using_alias_directive, un using_namespace_directive no aporta ningún miembro nuevo al espacio de declaración subyacente de la unidad de compilación o espacio de nombres, sino que afecta solo a la unidad de compilación o al cuerpo del 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.

Los namespace_name a los que hace referencia un using_namespace_directive se resuelven de la misma manera que el namespace_or_type_name al que hace referencia una 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_directive s en la misma unidad de compilación o el cuerpo del espacio de nombres no se ven afectados entre sí y se pueden escribir en cualquier orden.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.

Usar directivas estáticasUsing static directives

Un using_static_directive importa los tipos anidados y los miembros estáticos contenidos directamente en una declaración de tipos en la unidad de compilación o el cuerpo del espacio de nombres que se encuentra inmediatamente, lo que permite usar el identificador de cada miembro y tipo 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 de una unidad de compilación o un cuerpo de espacio de nombres que contiene un using_static_directive, se puede hacer referencia a los tipos anidados y miembros estáticos accesibles (excepto los métodos de extensión) contenidos directamente en la declaración del tipo dado.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(); }
    }
}

Anteriormente, dentro de las declaraciones de miembros del N2 espacio de nombres, los miembros estáticos y los tipos anidados de N1.A están disponibles directamente y, por tanto, el método N puede hacer referencia a los B M miembros y 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 los pone a disposición de la invocación de métodos de extensión (invocacionesde métodos 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 M de extensión contenido en N1.A , pero solo 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 produce un error en tiempo de compilación porque ningún miembro denominado M está 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 solo importa miembros y tipos declarados directamente en el tipo dado, no miembros y tipos declarados en 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

En el uso de las directivas de espacio de nombresse describen las ambigüedades entre varios using_namespace_directives y using_static_directives .Ambiguities between multiple using_namespace_directives and using_static_directives are discussed in Using namespace directives.

Miembros del espacio de nombresNamespace members

Un namespace_member_declaration es un namespace_declaration (declaraciones de espacio de nombres) o un type_declaration (declaraciones de tipos).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_declaration s y tales declaraciones aportan nuevos miembros al espacio de declaración subyacente de la unidad de compilación o el cuerpo del espacio de nombres que 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.

Declaraciones de tiposType declarations

Una type_declaration es una class_declaration (declaraciones de clase), una struct_declaration (declaraciones de struct), una interface_declaration (declaraciones de interfaz), una enum_declaration (declaraciones de enumeración) o una 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 producirse 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, una clase o un 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 tipo recién 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 se produce una declaración de tipos para un tipo T dentro de un espacio de nombres, clase o struct, el nombre completo del tipo recién declarado es N.T , donde N es el nombre completo del espacio de nombres, la clase o el struct que lo contiene.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 permitidos y el acceso predeterminado de una declaración de tipo dependen del contexto en el que tiene lugar la declaración (declarada accesibilidad):The permitted access modifiers and the default access for a type declaration depend on the context in which the declaration takes place (Declared accessibility):

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

Calificadores de alias de espacio de nombresNamespace 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 denominados identificadores a la izquierda y a la derecha.The namespace alias qualifier always appears between two identifiers referred to as the left-hand and right-hand identifiers. A diferencia del . calificador normal, el identificador de la parte izquierda del :: calificador solo se busca como 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 se define de la siguiente manera:A qualified_alias_member is defined as follows:

qualified_alias_member
    : identifier '::' identifier type_argument_list?
    ;

Un qualified_alias_member se puede usar como namespace_or_type_name (espacio de nombres y nombres de tipo) o como operando izquierdo en 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).

Una qualified_alias_member tiene una de las dos formas siguientes:A qualified_alias_member has one of two forms:

  • N::I<A1, ..., Ak>, donde N y I representan los 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 los identificadores.N::I, where N and I represent identifiers. (En este caso, K se considera cero).(In this case, K is considered to be zero.)

Con esta notación, el significado de un qualified_alias_member se determina de la manera siguiente:Using this notation, the meaning of a qualified_alias_member is determined as follows:

  • Si N es el identificador global , se busca en 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.
    • De lo 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.
    • De lo contrario, si el espacio de nombres global contiene un tipo denominado  I que tiene K   parámetros de tipo, el qualified_alias_member hace referencia a ese tipo construido con los argumentos de tipo especificados.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.
    • De lo contrario, el qualified_alias_member es indefinido y se produce un error en tiempo de compilación.Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.
  • De lo contrario, empezando por la declaración de espacio de nombres (declaraciones de espacio de nombres) que contiene inmediatamente el qualified_alias_member (si existe), continuando con cada declaración de espacio de nombres envolvente (si existe) y finalizando con la unidad de compilación que contiene la 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 declaración de espacio de nombres o la unidad de compilación contiene un using_alias_directive que N se asocia a un tipo, el qualified_alias_member no está definido y se produce un error en tiempo de compilación.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.
    • De lo contrario, si la declaración de espacio de nombres o la unidad de compilación contiene un extern_alias_directive o using_alias_directive que se asocia N con un espacio de nombres, entonces: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 a 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.
      • De lo contrario, si el espacio de nombres asociado a 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.
      • De lo contrario, si el espacio de nombres asociado a N contiene un tipo denominado  I que tiene K   parámetros de tipo, el qualified_alias_member hace referencia a ese tipo construido con los argumentos de tipo especificados.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.
      • De lo contrario, el qualified_alias_member es indefinido y se produce un error en tiempo de compilación.Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.
  • De lo contrario, el qualified_alias_member es indefinido y se produce un error en tiempo de compilación.Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.

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

Cada unidad de compilación y cuerpo del espacio de nombres tiene un espacio de declaración independiente para los alias extern 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, si bien el nombre de un alias extern o de uso de alias debe ser único en el conjunto de alias extern y usar alias declarados en la unidad de compilación o el cuerpo del espacio de nombres que contiene inmediatamente, se permite que un alias tenga el mismo nombre que un tipo o un espacio de nombres, siempre y cuando se use solo 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 segundo cuerpo del espacio de nombres porque tanto la clase A como el alias using 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. Por esta razón, el uso de A en el nombre completo A.Stream es ambiguo y provoca que se produzca un error en tiempo de compilación.For this reason, use of A in the qualified name A.Stream is ambiguous and causes a compile-time error to occur. Sin embargo, el uso de A con el :: calificador no es un error porque A solo se busca 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.