Partager via


Espaces de noms limités aux fichiers

Remarque

Cet article est une spécification de fonctionnalité. La spécification sert de document de conception pour la fonctionnalité. Il inclut les modifications de spécification proposées, ainsi que les informations nécessaires pendant la conception et le développement de la fonctionnalité. Ces articles sont publiés jusqu’à ce que les modifications de spécification proposées soient finalisées et incorporées dans la spécification ECMA actuelle.

Il peut y avoir des différences entre la spécification de la fonctionnalité et l’implémentation terminée. Ces différences sont consignées dans les notes pertinentes de la réunion de conception linguistique (LDM).

Vous pouvez en savoir plus sur le processus d’adoption des speclets de fonctionnalités dans la norme de langage C# dans l’article sur les spécifications .

Problème de champion : https://github.com/dotnet/csharplang/issues/137

Résumé

Les espaces de noms délimités aux fichiers utilisent un format moins détaillé pour le cas classique des fichiers contenant un seul espace de noms. Le format des espaces de noms limités aux fichiers est namespace X.Y.Z; (notez le point-virgule et l’absence d’accolades). Cela permet d’obtenir des fichiers comme suit :

namespace X.Y.Z;

using System;

class X
{
}

La sémantique est que l’utilisation du formulaire namespace X.Y.Z; équivaut à écrire namespace X.Y.Z { ... } où le reste du fichier suivant l’espace de noms délimité au fichier se trouve dans la section ... d’une déclaration d’espace de noms standard.

Motivation

L’analyse de l’écosystème C# montre qu’environ 99,7 fichiers% sont tous l’une des formes suivantes :

namespace X.Y.Z
{
    // usings

    // types
}

or

// usings

namespace X.Y.Z
{
    // types
}

Cependant, ces deux formes forcent l’utilisateur à mettre en retrait la majorité de son code et à ajouter une bonne quantité de formalités pour ce qui n'est en réalité qu'un concept très simple. Cela affecte la clarté, utilise l'espace horizontal et vertical, et est souvent insatisfaisant pour les utilisateurs habitués à C# et provenant d'autres langages (qui ont généralement moins de cérémonial ici).

L’objectif principal de la fonctionnalité est donc de répondre aux besoins de la majorité de l’écosystème avec moins de code générique inutile.

Conception détaillée

Cette proposition prend la forme d’une modification de la section (§14.2) de la spécification relative aux unités de compilation.

Diff

Une compilation_unit définit la structure globale d’un fichier source. Une unité de compilation se compose de zéro ou plusieurs using_directives, suivis de zéro ou plusieurs global_attributes, puis de zéro ou plusieurs namespace_member_declarations.

Une compilation_unit définit la structure globale d’un fichier source. Une unité de compilation se compose de zéro ou plusieurs using_directives, puis zéro ou plusieurs global_attributes, et enfin un compilation_unit_body. Un compilation_unit_body peut être une file_scoped_namespace_declaration ou zéro ou plusieurs statements et 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
    ;

... inchangé...

Une file_scoped_namespace_declaration contribue aux membres correspondant à la namespace_declaration à laquelle elle est sémantiquement équivalente. Pour plus d’informations, Consultez (Déclarations d’espaces de noms).

Déclarations d'espace de noms

Un namespace_declaration se compose du mot clé namespace, suivi d’un nom et d’un corps d’espace de noms, éventuellement suivis d’un point-virgule. Une file_scoped_namespace_declaration se compose du mot clé namespace, suivi d’un nom d’un espace de noms, d’un point-virgule et d’une liste facultative de extern_alias_directives, using_directives et type_declarations.

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

... unchanged ...

... inchangé...

les deux déclarations d’espace de noms ci-dessus contribuent au même espace de déclaration, dans ce cas en déclarant deux classes avec les noms complets N1.N2.A et N1.N2.B. Étant donné que les deux déclarations contribuent à la même espace de déclaration, il aurait été une erreur si chacune contenait une déclaration d’un membre portant le même nom.

Une file_scoped_namespace_declaration permet d’écrire une déclaration d’espace de noms sans le bloc { ... }. Par exemple:

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

est sémantiquement équivalent à

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

Plus précisément, une file_scoped_namespace_declaration est traitée comme une namespace_declaration au même emplacement dans le compilation_unit avec le même qualified_identifier. Les extern_alias_directive, les using_directives et les type_declarations de cette file_scoped_namespace_declaration agissent comme s’ils étaient déclarés dans le même ordre dans le namespace_body de cette namespace_declaration.

Un fichier source ne peut pas contenir à la fois un file_scoped_namespace_declaration et un namespace_declaration. Un fichier source ne peut pas contenir plusieurs file_scoped_namespace_declarations. Un compilation_unit ne peut pas contenir à la fois un file_scoped_namespace_declaration et n’importe quelle instruction de niveau supérieur s. type_declarations ne peut pas précéder une file_scoped_namespace_declaration.

Alias externes

... inchangé...