次の方法で共有


ファイル スコープの名前空間

手記

この記事は機能仕様です。 仕様は、機能の設計ドキュメントとして機能します。 これには、提案された仕様の変更と、機能の設計と開発時に必要な情報が含まれます。 これらの記事は、提案された仕様の変更が最終決定され、現在の ECMA 仕様に組み込まれるまで公開されます。

機能の仕様と完成した実装の間には、いくつかの違いがある可能性があります。 これらの違いは、関連する 言語設計会議 (LDM) ノートでキャプチャされます。

機能仕様を C# 言語標準に導入するプロセスの詳細については、仕様に関する記事を参照してください。

チャンピオンの課題: https://github.com/dotnet/csharplang/issues/137

概要

ファイル スコープの名前空間は、通常 1 つの名前空間のみを含むファイルに対して、冗長性の低い形式が使用されます。 ファイル スコープの名前空間形式は namespace X.Y.Z; です (セミコロンと中かっこがないことに注意してください)。 これにより、次のようなファイルを使用できます。

namespace X.Y.Z;

using System;

class X
{
}

セマンティクスは、namespace X.Y.Z; 形式の使用は、ファイル スコープの名前空間の後のファイルの残りの部分が標準の名前空間宣言の ... セクションにある namespace X.Y.Z { ... } を記述することと同じです。

モチベーション

C# エコシステムの分析では、約 99.7% ファイルがすべて次のいずれかの形式であることを示しています。

namespace X.Y.Z
{
    // usings

    // types
}

または

// usings

namespace X.Y.Z
{
    // types
}

ただし、どちらの形式でも、ユーザーは自分のコードの大部分をインデントし、実質的に非常に基本的な概念であるものに対してかなりの量の儀式を追加するように強制されます。 これは、分かりやすさに影響を与え、水平方向と垂直方向のスペースを使用するため、C# に慣れているユーザーや他の言語(ここでは一般的に定型的な要素が少ない)を利用しているユーザーにとって多くの場合満足できないことがあります。

そのため、この機能の主な目標は、不要な定型文を使用して、エコシステムの大部分のニーズを満たすことです。

詳細な設計

この提案は、仕様の既存のコンパイル単位 (§14.2) セクションとの差分の形式をとります。

[Diff]

compilation_unit は、ソース ファイルの全体的な構造を定義します。 コンパイル単位は、0 個以上の using_directives の後に 0 個以上の global_attributes が続き、その後に 0 個以上の namespace_member_declarations が続きます。

compilation_unit は、ソース ファイルの全体的な構造を定義します。 コンパイル単位は、0 個以上の using_directiveから成り、その後に 0 個以上の global_attributes が続き、その後に compilation_unit_bodyが続きます。 compilation_unit_body には、file_scoped_namespace_declaration または 0 個以上の ステートメント、また namespace_member_declaration を指定できます。

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
    ;

変わらずに…

file_scoped_namespace_declaration は、意味的に同等の namespace_declaration に対応するメンバーを提供します。 詳細については、(名前空間宣言) を参照してください。

名前空間宣言

namespace_declaration は、キーワード namespace、名前空間の名前と本文、必要に応じてセミコロンで構成されます。 file_scoped_namespace_declaration は、キーワード namespace、名前空間名、セミコロン、およびオプションの extern_alias_directiveusing_directivetype_declaration のリストで構成されます。

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

... unchanged ...

... 変更なし ...

上記の 2 つの名前空間宣言は、同じ宣言空間に寄与します。この場合、完全修飾名を持つ 2 つのクラスを N1.N2.A および N1.N2.Bで宣言します。 2 つの宣言は同じ宣言空間に影響するため、それぞれが同じ名前のメンバーの宣言を含む場合はエラーでした。

file_scoped_namespace_declaration では、{ ... } ブロックなしで名前空間宣言を記述できます。 例えば:

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

意味的に同等である

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

具体的には、file_scoped_namespace_declaration は、同じ qualified_identifierを持つ compilation_unit 内の同じ場所にある namespace_declaration と同じように扱われます。 その file_scoped_namespace_declarationextern_alias_directiveusing_directivetype_declarationは、その namespace_declarationnamespace_body 内で同じ順序で宣言されたかのように動作します。

ソース ファイルには、file_scoped_namespace_declarationnamespace_declarationの両方を含めることはできません。 ソース ファイルに複数の file_scoped_namespace_declaration を含めることはできません。 compilation_unit には、file_scoped_namespace_declaration とトップレベルの ステートメントを同時に含めることはできません。 type_declarationは、file_scoped_namespace_declarationの前に置くことはできません。

Extern エイリアス

... 変更されていない ...