命名空間Namespaces

C# 程式組織方式使用命名空間。C# programs are organized using namespaces. 命名空間用作為程式,「 內部 」 的組織系統和 「 外部 」 的組織系統 — 一種呈現會公開至其他程式的程式項目。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.

Using 指示詞 (Using 指示詞) 提供給方便使用的命名空間。Using directives (Using directives) are provided to facilitate the use of namespaces.

編譯單位Compilation units

A compilation_unit定義原始程式檔的整體結構。A compilation_unit defines the overall structure of a source file. 編譯單位包含零或多個using_directives 後面接著零或多個global_attributes後面接著零或多個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*
    ;

C# 程式包含了一個或多個編譯單位,每一個都包含不同的原始程式檔中。A C# program consists of one or more compilation units, each contained in a separate source file. C# 程式編譯時,所有的編譯單位都會一起處理。When a C# program is compiled, all of the compilation units are processed together. 因此,編譯單位可以彼此相依,可能是以循環方式。Thus, compilation units can depend on each other, possibly in a circular fashion.

Using_directive秒的編譯單位會影響global_attributesnamespace_member_declaration該編譯單位中,但有任何作用其他的編譯單位。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.

Global_attributes (屬性) 的編譯單位允許的目標組件和模組的屬性規格。The global_attributes (Attributes) of a compilation unit permit the specification of attributes for the target assembly and module. 組件和模組做為型別的實體容器。Assemblies and modules act as physical containers for types. 組件可能包含數個實際分開的模組。An assembly may consist of several physically separate modules.

Namespace_member_declaration之程式的每個編譯單位參與稱為全域命名空間的單一宣告空間的成員。The namespace_member_declarations of each compilation unit of a program contribute members to a single declaration space called the global namespace. 例如: For example:

檔案A.cs:File A.cs:

class A {}

檔案B.cs:File B.cs:

class B {}

兩個編譯單位參與單一全域命名空間,在此情況下宣告兩個類別的完整格式名稱具有ABThe two compilation units contribute to the single global namespace, in this case declaring two classes with the fully qualified names A and B. 因為兩個編譯單位參與相同的宣告空間,就會發生錯誤如果每一個包含成員具有相同名稱的宣告。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.

命名空間宣告Namespace declarations

A namespace_declaration組成關鍵字namespace,後面加上命名空間名稱和主體,或者後面接著一個分號。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* '}'
    ;

A namespace_declaration中的最上層宣告可能會發生compilation_unit或在另一個成員宣告namespace_declarationA namespace_declaration may occur as a top-level declaration in a compilation_unit or as a member declaration within another namespace_declaration. namespace_declaration中的最上層宣告,就會發生compilation_unit,命名空間會變成全域命名空間的成員。When a namespace_declaration occurs as a top-level declaration in a compilation_unit, the namespace becomes a member of the global namespace. namespace_declaration就會發生在另一個namespace_declaration,內部的命名空間會變成外部命名空間的成員。When a namespace_declaration occurs within another namespace_declaration, the inner namespace becomes a member of the outer namespace. 在任一情況下,必須是包含命名空間中的唯一命名空間名稱。In either case, the name of a namespace must be unique within the containing namespace.

命名空間都是隱含public和命名空間宣告不能包含任何存取修飾詞。Namespaces are implicitly public and the declaration of a namespace cannot include any access modifiers.

namespace_body,選擇性using_directives 匯入其他命名空間、 類型和成員,以便直接而不是透過限定名稱所參考的名稱。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. 選擇性namespace_member_declarations 提供的命名空間的宣告空間的成員。The optional namespace_member_declarations contribute members to the declaration space of the namespace. 請注意,所有using_directives 必須出現在成員的任何宣告之前。Note that all using_directives must appear before any member declarations.

Qualified_identifiernamespace_declaration以單一識別項或分隔的識別項的序列可能是 「."語彙基元。The qualified_identifier of a namespace_declaration may be a single identifier or a sequence of identifiers separated by "." tokens. 第二個表單允許程式以定義巢狀命名空間,而不需要語彙巢狀數個命名空間宣告。The latter form permits a program to define a nested namespace without lexically nesting several namespace declarations. 例如,套用至物件的For example,

namespace N1.N2
{
    class A {}

    class B {}
}

在語意上等於is semantically equivalent to

namespace N1
{
    namespace N2
    {
        class A {}

        class B {}
    }
}

命名空間是無限的但兩個具有相同的完整限定名稱的命名空間宣告參與相同的宣告空間 (宣告)。Namespaces are open-ended, and two namespace declarations with the same fully qualified name contribute to the same declaration space (Declarations). 在範例In the example

namespace N1.N2
{
    class A {}
}

namespace N1.N2
{
    class B {}
}

上面的兩個命名空間宣告提供給相同的宣告空間,在此情況下宣告兩個類別的完整格式名稱具有N1.N2.AN1.N2.Bthe 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. 因為這兩種宣告參與相同的宣告空間,就會發生錯誤,如果每個都包含具有相同名稱的成員的宣告。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.

外部別名Extern aliases

Extern_alias_directive引進識別項,做為命名空間的別名。An extern_alias_directive introduces an identifier that serves as an alias for a namespace. 別名命名空間的規格是外部程式的原始程式碼,而且也適用於巢狀命名空間的別名命名空間。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 ';'
    ;

範圍extern_alias_directive擴充using_directives global_attributesnamespace_member_declaration立即包含編譯單位或命名空間主體的 s。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.

在編譯單位或命名空間主體中包含extern_alias_directive,所導入的識別項extern_alias_directive可用來參考別名命名空間。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. 它是編譯時期錯誤識別碼是 word globalIt is a compile-time error for the identifier to be the word global.

Extern_alias_directive讓別名可在特定的編譯單位或命名空間主體中,但它並沒有提供給基礎的宣告空間的任何新成員。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. 亦即extern_alias_directive不是可轉移的但相反地,會影響僅編譯單位或命名空間主體中發生。In other words, an extern_alias_directive is not transitive, but, rather, affects only the compilation unit or namespace body in which it occurs.

下列程式會宣告並使用兩個外部別名XY,每個代表不同的命名空間階層的根的: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;
}

這個程式會宣告是否存在外部別名XY,但實際的別名定義是外部程式。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.B類別現在可做為參考X.N.BY.N.B,或者,您也可以使用命名空間別名限定詞,X::N.BY::N.BThe 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. 如果程式宣告外部別名提供沒有外部的定義,就會發生錯誤。An error occurs if a program declares an extern alias for which no external definition is provided.

using 指示詞Using directives

Using 指示詞方便使用的命名空間和其他命名空間中定義的類型。Using directives facilitate the use of namespaces and types defined in other namespaces. 使用指示詞影響的名稱解析程序namespace_or_type_names (命名空間和類型名稱) 和simple_names (簡單名稱),但不同於 using 指示詞的宣告,並不會提供基礎的宣告空間的編譯單位或在其中使用的命名空間的新成員。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
    ;

A using_alias_directive (Using 別名指示詞) 導入了命名空間或類型的別名。A using_alias_directive (Using alias directives) introduces an alias for a namespace or type.

A using_namespace_directive (Using 命名空間指示詞) 匯入命名空間的型別成員。A using_namespace_directive (Using namespace directives) imports the type members of a namespace.

A using_static_directive (Using 靜態指示詞) 匯入巢狀的類型和類型的靜態成員。A using_static_directive (Using static directives) imports the nested types and static members of a type.

範圍using_directive擴充namespace_member_declaration立即包含編譯單位或命名空間主體的 s。The scope of a using_directive extends over the namespace_member_declarations of its immediately containing compilation unit or namespace body. 範圍using_directive特別不包含其對等using_directives。The scope of a using_directive specifically does not include its peer using_directives. 因此,對等互連using_directives 並不會影響彼此,並在其中寫入的順序不重要。Thus, peer using_directives do not affect each other, and the order in which they are written is insignificant.

Using 別名指示詞Using alias directives

A using_alias_directive導入做為別名的命名空間或型別,直接封入的編譯單位或命名空間主體中的識別項。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 ';'
    ;

成員宣告中包含的編譯單位或命名空間主體using_alias_directive,所導入的識別項using_alias_directive可以用來參考指定命名空間或類型。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. 例如:For example:

namespace N1.N2
{
    class A {}
}

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

    class B: A {}
}

上述成員宣告中N3命名空間A為其別名N1.N2.A,因此類別N3.B衍生自類別N1.N2.AAbove, 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. 可取得相同的效果,請建立別名Rfor N1.N2 ,接著參考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 {}
}

識別碼using_alias_directive編譯單位或立即包含命名空間的宣告空間內必須是唯一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. 例如: For example:

namespace N3
{
    class A {}
}

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

上述N3已包含的成員A,因此它是編譯時期錯誤using_alias_directive使用該識別項。Above, N3 already contains a member A, so it is a compile-time error for a using_alias_directive to use that identifier. 同樣地,它是兩個以上的編譯時期錯誤using_alias_directive相同編譯單位或命名空間主體內宣告相同名稱的別名。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.

A using_alias_directive讓別名可在特定的編譯單位或命名空間主體中,但它並沒有提供給基礎的宣告空間的任何新成員。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. 亦即using_alias_directive並非可轉移而是會影響僅編譯單位或命名空間主體中發生。In other words, a using_alias_directive is not transitive but rather affects only the compilation unit or namespace body in which it occurs. 在範例In the example

namespace N3
{
    using R = N1.N2;
}

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

範圍using_alias_directive導入R只會延伸到其中它包含,命名空間內的成員宣告讓R不明第二個命名空間宣告中。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. 不過,放置using_alias_directive包含編譯單位會造成要供這兩個命名空間宣告中的別名: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 {}
}

就像一般的成員名稱則是所引進using_alias_directives 會隱藏名稱相似的成員,在巢狀範圍中。Just like regular members, names introduced by using_alias_directives are hidden by similarly named members in nested scopes. 在範例In the example

using R = N1.N2;

namespace N3
{
    class R {}

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

參考R.A中的宣告B造成編譯時期錯誤,因為R是指N3.R,而非N1.N2the reference to R.A in the declaration of B causes a compile-time error because R refers to N3.R, not N1.N2.

順序using_alias_directives 會寫入不具有任何重要性,並解決namespace_or_type_name所參考using_alias_directive不會受到using_alias_directive本身或其他using_directive立即包含編譯單位或命名空間主體內。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. 亦即namespace_or_type_nameusing_alias_directive如同立即包含的編譯單位或命名空間主體有不是解析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. A using_alias_directive不過可能會受到extern_alias_directive立即包含編譯單位或命名空間主體內。A using_alias_directive may however be affected by extern_alias_directives in the immediately containing compilation unit or namespace body. 在範例In 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
}

上次using_alias_directive導致編譯時期錯誤,因為它不會受到第一個using_alias_directivethe last using_alias_directive results in a compile-time error because it is not affected by the first using_alias_directive. 第一個using_alias_directive不會導致錯誤自外部別名的範圍E包括using_alias_directiveThe first using_alias_directive does not result in an error since the scope of the extern alias E includes the using_alias_directive.

A using_alias_directive可以建立任何命名空間或類型,包括在其中出現的命名空間的別名,而該命名空間內的任何命名空間或類型巢狀。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.

透過別名存取命名空間或類型,就會產生完全相同的結果做為透過它的宣告名稱存取該命名空間或類型。Accessing a namespace or type through an alias yields exactly the same result as accessing that namespace or type through its declared name. 例如,假設For 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
    }
}

名稱N1.N2.AR1.N2.A,並R2.A對等項目和所有參考的類別完整的名稱是N1.N2.Athe 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.

使用別名時,可以封閉式建構類型的名稱,但無法命名為未繫結的泛型型別宣告未提供類型引數。Using aliases can name a closed constructed type, but cannot name an unbound generic type declaration without supplying type arguments. 例如: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
}

使用命名空間指示詞Using namespace directives

A using_namespace_directive匯入到與其直接封入編譯單位或命名空間主體中,包含命名空間中啟用無限制地使用每個類型的識別項的型別。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 ';'
    ;

成員宣告中包含的編譯單位或命名空間主體using_namespace_directive,可以直接參考包含在指定的命名空間中的型別。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. 例如: For example:

namespace N1.N2
{
    class A {}
}

namespace N3
{
    using N1.N2;

    class B: A {}
}

上述在成員宣告內N3命名空間、 類型成員N1.N2可直接使用,並因此類別N3.B衍生自類別N1.N2.AAbove, 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.

A using_namespace_directive匯入包含在指定的命名空間的類型,但特別是不會匯入巢狀命名空間。A using_namespace_directive imports the types contained in the given namespace, but specifically does not import nested namespaces. 在範例In the example

namespace N1.N2
{
    class A {}
}

namespace N3
{
    using N1;

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

using_namespace_directive中所包含的型別匯N1,但不是命名空間巢狀方式置於N1the using_namespace_directive imports the types contained in N1, but not the namespaces nested in N1. 因此,若要參考N2.A中的宣告B導致編譯時期錯誤,因為沒有任何成員命名為N2範圍內。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.

不同於using_alias_directive,則using_namespace_directive可以匯入識別碼已在封入的編譯單位或命名空間主體中定義的類型。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. 作用中,名稱匯入using_namespace_directive隱藏名稱相似的成員,在封入的編譯單位或命名空間主體中。In effect, names imported by a using_namespace_directive are hidden by similarly named members in the enclosing compilation unit or namespace body. 例如:For example:

namespace N1.N2
{
    class A {}

    class B {}
}

namespace N3
{
    using N1.N2;

    class A {}
}

這裡,在成員宣告內N3命名空間A是指N3.A而非N1.N2.AHere, within member declarations in the N3 namespace, A refers to N3.A rather than N1.N2.A.

當一個以上的命名空間或類型匯入using_namespace_directives 或using_static_directive相同編譯單位或命名空間主體中包含相同名稱,也就是參考類型該名稱作為type_name會被視為模稜兩可。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. 在範例In the example

namespace N1
{
    class A {}
}

namespace N2
{
    class A {}
}

namespace N3
{
    using N1;

    using N2;

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

兩者N1N2包含成員A,而且因為N3匯入這兩者,參考AN3是編譯時期錯誤。both N1 and N2 contain a member A, and because N3 imports both, referencing A in N3 is a compile-time error. 在此情況下,衝突是可解析是透過參考限定A,或藉由引進using_alias_directive ,會挑選特定AIn 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. 例如: For example:

namespace N3
{
    using N1;

    using N2;

    using A = N1.A;

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

此外,當一個以上的命名空間或類型匯入using_namespace_directives 或using_static_directive相同編譯單位或命名空間主體中包含類型或成員相同的名稱,該名稱參考simple_name會被視為模稜兩可。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. 在範例In 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 包含型別成員A,並C包含靜態欄位A,而且因為N2匯入這兩者,參考A做為simple_name是模稜兩可和編譯時間發生錯誤。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.

像是using_alias_directive,則using_namespace_directive並沒有提供任何新的成員,在基礎的宣告空間的編譯單位或命名空間,但而是只會影響編譯單位或命名空間主體中出現。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.

Namespace_name所參考using_namespace_directive解析為相同的方式namespace_or_type_name所參考using_alias_directiveThe 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. 因此, using_namespace_directive相同編譯單位或命名空間主體中不會影響彼此,並可以依照任何順序來寫入。Thus, using_namespace_directives in the same compilation unit or namespace body do not affect each other and can be written in any order.

Using 靜態指示詞Using static directives

A using_static_directive匯入巢狀型別和靜態成員直接包含在型別宣告成與其直接封入編譯單位或命名空間主體中,啟用 為每個成員和類型的識別碼使用無限制。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 ';'
    ;

成員宣告中包含的編譯單位或命名空間主體using_static_directive,存取巢狀類型和靜態成員 (不包括擴充方法) 的宣告中直接包含指定的型別可以直接參考。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. 例如: 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(); }
    }
}

上述成員宣告中N2命名空間的靜態成員和巢狀型別N1.A可以直接使用,因此方法N能夠參考BM的成員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.

A using_static_directive特別不匯入延伸模組方法,直接做為靜態的方法,但可讓這些擴充方法引動過程版本 (擴充方法引動過程)。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). 在範例In 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
        }
    }
}

using_static_directive擴充方法會匯入M中所包含N1.A,但只作為擴充方法。the using_static_directive imports the extension method M contained in N1.A, but only as an extension method. 因此,第一次參考M中的主體B.N導致編譯時期錯誤,因為沒有任何成員命名為M範圍內。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.

A using_static_directive只會匯入成員和指定的型別,直接宣告的類型沒有成員和型別宣告基底類別中。A using_static_directive only imports members and types declared directly in the given type, not members and types declared in base classes.

待辦事項:範例TODO: Example

多個之間的模稜兩可using_namespace_directivesusing_static_directives討論Using 命名空間指示詞Ambiguities between multiple using_namespace_directives and using_static_directives are discussed in Using namespace directives.

命名空間成員Namespace members

A namespace_member_declarationnamespace_declaration (命名空間宣告) 或type_declaration (型別宣告)。A namespace_member_declaration is either a namespace_declaration (Namespace declarations) or a type_declaration (Type declarations).

namespace_member_declaration
    : namespace_declaration
    | type_declaration
    ;

編譯單位或命名空間主體可以包含namespace_member_declarations 中,而這類宣告提供給基礎的宣告空間包含的編譯單位或命名空間主體的新成員。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.

型別宣告Type declarations

A type_declarationclass_declaration (類別宣告),則struct_declaration (結構宣告),則interface_declaration (介面宣告),則enum_declaration (列舉宣告),或有delegate_declaration (委派宣告)。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
    ;

A type_declaration為編譯單位的最上層宣告或命名空間、 類別或結構內宣告的成員可能會發生。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.

當型別宣告型別的T會顯示新宣告型別的完整的名稱就是為編譯單位的最上層宣告TWhen 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. 當型別宣告型別的T就會發生的命名空間、 類別或結構的新宣告的型別完整名稱是N.T,其中N是包含命名空間、 類別或結構的完整的名稱。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.

在類別內宣告的型別或結構稱為巢狀型別 (巢狀型別)。A type declared within a class or struct is called a nested type (Nested types).

允許的存取修飾詞和型別宣告的預設存取權取決於宣告進行的內容 (宣告存取範圍):The permitted access modifiers and the default access for a type declaration depend on the context in which the declaration takes place (Declared accessibility):

  • 在編譯單位或命名空間中宣告的型別可以有publicinternal存取。Types declared in compilation units or namespaces can have public or internal access. 預設值是internal存取。The default is internal access.
  • 在類別中宣告的型別可以有publicprotected internalprotectedinternal,或private存取。Types declared in classes can have public, protected internal, protected, internal, or private access. 預設值是private存取。The default is private access.
  • 在結構中宣告的型別可以有publicinternal,或private存取。Types declared in structs can have public, internal, or private access. 預設值是private存取。The default is private access.

命名空間別名限定詞Namespace alias qualifiers

命名空間別名限定詞::讓您能夠保證型別名稱查閱會受到新的類型和成員的簡介。The namespace alias qualifier :: makes it possible to guarantee that type name lookups are unaffected by the introduction of new types and members. 命名空間別名限定詞永遠會出現稱為左側和右側的識別項的兩個識別碼之間。The namespace alias qualifier always appears between two identifiers referred to as the left-hand and right-hand identifiers. 不同於一般.限定詞,左側的識別項的::限定詞查詢最多只能為 extern 或使用別名。Unlike the regular . qualifier, the left-hand identifier of the :: qualifier is looked up only as an extern or using alias.

A qualified_alias_member定義如下:A qualified_alias_member is defined as follows:

qualified_alias_member
    : identifier '::' identifier type_argument_list?
    ;

A qualified_alias_member可用來當做namespace_or_type_name (命名空間和型別名稱) 或中的左運算元為member_access(成員存取)。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).

A qualified_alias_member有兩種形式之一:A qualified_alias_member has one of two forms:

  • N::I<A1, ..., Ak>其中NI表示識別項,以及<A1, ..., Ak>是型別引數清單。N::I<A1, ..., Ak>, where N and I represent identifiers, and <A1, ..., Ak> is a type argument list. (K總是至少一個。)(K is always at least one.)
  • N::I其中NI代表識別項。N::I, where N and I represent identifiers. (在此情況下,K則皆為零。)(In this case, K is considered to be zero.)

使用這個標記法的意義qualified_alias_member判斷方式如下:Using this notation, the meaning of a qualified_alias_member is determined as follows:

  • 如果N是識別項global,然後搜尋全域命名空間I:If N is the identifier global, then the global namespace is searched for I:

    • 如果全域命名空間包含名為命名空間 IK為零,則qualified_alias_member指的是該命名空間。If the global namespace contains a namespace named I and K is zero, then the qualified_alias_member refers to that namespace.
    • 否則,如果全域命名空間包含名為非泛型型別 IK為零,則qualified_alias_member參考該型別。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.
    • 否則,如果全域命名空間包含名為的型別 I具有K 型別參數,則qualified_alias_member建構具有指定的型別引數的型別參考。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.
    • 否則,請qualified_alias_member是未定義,而且會發生編譯時期錯誤。Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.
  • 否則,開頭的命名空間宣告 (命名空間宣告) 立即包含qualified_alias_member (如果有的話),繼續使用每個封入的命名空間宣告(如果有的話),並包含編譯單位以作為結束qualified_alias_member,直到找到實體為止,會評估下列步驟: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:

    • 如果包含的命名空間宣告或編譯單位using_alias_directive建立關聯的N類型,則qualified_alias_member是未定義和編譯時間會發生錯誤。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.
    • 否則,如果命名空間宣告或編譯單位包含extern_alias_directive或是using_alias_directive建立關聯的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:
      • 如果命名空間相關聯N包含名為命名空間 IK為零,則qualified_alias_member指的是該命名空間。If the namespace associated with N contains a namespace named I and K is zero, then the qualified_alias_member refers to that namespace.
      • 否則,如果命名空間相關聯N包含名為非泛型型別 IK為零,則qualified_alias_member參考該型別。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.
      • 否則,如果命名空間相關聯N包含名為的型別 I具有K 型別參數,則qualified_alias_member指的是以建構類型指定的型別引數。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.
      • 否則,請qualified_alias_member是未定義,而且會發生編譯時期錯誤。Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.
  • 否則,請qualified_alias_member是未定義,而且會發生編譯時期錯誤。Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.

請注意,使用參考類型的別名的命名空間別名限定詞會使編譯時期錯誤。Note that using the namespace alias qualifier with an alias that references a type causes a compile-time error. 也請注意,如果識別項 Nglobal,則即使沒有別名建立關聯的使用中全域命名空間中,執行查閱global與型別或命名空間。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.

別名的唯一性Uniqueness of aliases

每個編譯單位和命名空間主體具有個別的宣告空間,以讓外部別名和使用別名。Each compilation unit and namespace body has a separate declaration space for extern aliases and using aliases. 因此,雖然外部別名,或使用別名的名稱必須是唯一的外部別名集合中,並使用別名宣告直接包含的編譯單位或命名空間主體中,別名不允許有相同名稱的型別或命名空間,只要我只能搭配使用 t::限定詞。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.

在範例In 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
    }
}

名稱A第二個命名空間主體中有兩個可能的意義,因為這兩個類別A並使用別名A範圍內。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. 基於這個理由,利用A限定名稱中A.Stream模稜兩可,並會導致發生編譯時期錯誤。For this reason, use of A in the qualified name A.Stream is ambiguous and causes a compile-time error to occur. 不過,使用A具有::限定詞不是錯誤因為A查閱只會為命名空間別名。However, use of A with the :: qualifier is not an error because A is looked up only as a namespace alias.