Compartir a través de


Espacios de nombres con ámbito de archivo

Nota

Este artículo es una especificación de características. La especificación actúa como documento de diseño de la característica. Incluye cambios de especificación propuestos, junto con la información necesaria durante el diseño y el desarrollo de la característica. Estos artículos se publican hasta que se finalizan los cambios de especificación propuestos e se incorporan en la especificación ECMA actual.

Puede haber algunas discrepancias entre la especificación de características y la implementación completada. Esas diferencias se recogen en las notas de la reunión de diseño de lenguaje (LDM) correspondientes.

Puede obtener más información sobre el proceso de adopción de especificaciones de características en el estándar del lenguaje C# en el artículo sobre las especificaciones de .

Resumen

Los espacios de nombres con ámbito de archivo usan un formato menos detallado para el caso típico de archivos que contienen solo un espacio de nombres. El formato de espacio de nombres con ámbito de archivo es namespace X.Y.Z; (tenga en cuenta el punto y coma y la falta de llaves). Esto permite archivos como los siguientes:

namespace X.Y.Z;

using System;

class X
{
}

La semántica es que el uso de la forma namespace X.Y.Z; equivale a escribir namespace X.Y.Z { ... }, donde el resto del archivo que sigue al espacio de nombres con ámbito de archivo se encuentra en la sección ... de una declaración de espacio de nombres estándar.

Motivación

El análisis del ecosistema de C# muestra que aproximadamente 99,7 archivos% son todos de cualquiera de estos formatos:

namespace X.Y.Z
{
    // usings

    // types
}

o

// usings

namespace X.Y.Z
{
    // types
}

Sin embargo, ambas formas obligan al usuario a poner sangría a la mayor parte del código y agregar una cantidad justa de formalidades para lo que es efectivamente un concepto muy básico. Esto afecta a la claridad, usa el espacio horizontal y vertical, y a menudo no es satisfactorio para los usuarios acostumbrados a C# y procedentes de otros lenguajes (que normalmente tienen menos formalidades a este respecto).

Por lo tanto, el objetivo principal de la funcionalidad es satisfacer las necesidades de la mayoría del ecosistema con menos código repetitivo innecesario.

Diseño detallado

Esta propuesta adopta la forma de un diff para las unidades de compilación existentes (§14.2) de la especificación.

Diferencias

Un compilation_unit define la estructura general de un archivo de origen. Una unidad de compilación consta de cero o más using_directives seguida de cero o más global_attributes seguido de cero o más namespace_member_declarations.

Un compilation_unit define la estructura general de un archivo de origen. Una unidad de compilación consta de cero o más using_directives seguida de cero o más global_attributes seguido de un compilation_unit_body. Un compilation_unit_body puede ser una file_scoped_namespace_declaration o puede contener cero o más statements y namespace_member_declarations.

compilation_unit
~~    : extern_alias_directive* using_directive* global_attributes? namespace_member_declaration*~~
    : extern_alias_directive* using_directive* global_attributes? compilation_unit_body
    ;

compilation_unit_body
    : statement* namespace_member_declaration*
    | file_scoped_namespace_declaration
    ;

... inalterado...

Una file_scoped_namespace_declaration contribuirá a los miembros correspondientes a la namespace_declaration a la que es semánticamente equivalente. Consulte (Declaraciones de espacio de nombres) para obtener más información.

Declaraciones de espacio de nombres

Una namespace_declaration consta de la palabra clave namespace, seguida de un nombre de espacio de nombres y un cuerpo, seguido opcionalmente de un punto y coma. Una file_scoped_namespace_declaration consta de la palabra clave namespace, seguida de un nombre de espacio de nombres, un punto y coma y una lista opcional de extern_alias_directives, using_directives y type_declarations.

namespace_declaration
    : 'namespace' qualified_identifier namespace_body ';'?
    ;
    
file_scoped_namespace_declaration
    : 'namespace' qualified_identifier ';' extern_alias_directive* using_directive* type_declaration*
    ;

... unchanged ...

... inalterado...

las dos declaraciones de espacio de nombres anteriores contribuyen al mismo espacio de declaración, en este caso declarando dos clases con los nombres completos N1.N2.A y N1.N2.B. Dado que las dos declaraciones contribuyen al mismo espacio de declaración, habría sido un error si cada una contenía una declaración de un miembro con el mismo nombre.

Una file_scoped_namespace_declaration permite escribir una declaración de espacio de nombres sin el bloque { ... }. Por ejemplo:

extern alias A;
namespace Name;
using B;
class C
{
}

es semánticamente equivalente a

extern alias A;
namespace Name
{
    using B;
    class C
    {
    }
}

En concreto, una file_scoped_namespace_declaration se trata igual que una namespace_declaration en la misma ubicación de la compilation_unit con el mismo qualified_identifier. Las extern_alias_directives, using_directives y type_declarations de esa file_scoped_namespace_declaration actúan como si estuvieran declaradas en el mismo orden dentro del namespace_body de esa namespace_declaration.

Un archivo de origen no puede contener un file_scoped_namespace_declaration y un namespace_declaration. Un archivo de origen no puede contener varias file_scoped_namespace_declarations. Una compilation_unit no puede contener una file_scoped_namespace_declaration ni statements de nivel superior. type_declarations no puede preceder a una file_scoped_namespace_declaration.

Alias externos

... inalterado...