다음을 통해 공유


네임스페이스 14개

14.1 일반

C# 프로그램은 네임스페이스를 사용하여 구성됩니다. 네임스페이스는 프로그램에 대한 "내부" 조직 시스템 및 다른 프로그램에 노출되는 프로그램 요소를 표시하는 방법인 "외부" 조직 시스템으로 사용됩니다.

네임스페이스를 쉽게 사용할 수 있도록 지시문(§14.5)을 사용합니다.

14.2 컴파일 단위

compilation_unit 0개 이상의 extern_alias_directive뒤에 0개 이상의 using_directive, 0개 또는 1개의 global_attributes, 0개 이상의 namespace_member_declaration로 구성됩니다. compilation_unit 입력의 전체 구조를 정의합니다.

compilation_unit
    : extern_alias_directive* using_directive* global_attributes?
      namespace_member_declaration*
    ;

C# 프로그램은 하나 이상의 컴파일 단위로 구성됩니다. C# 프로그램이 컴파일되면 모든 컴파일 단위가 함께 처리됩니다. 따라서 컴파일 단위는 순환 방식으로 서로에 따라 달라질 수 있습니다.

컴파일 단위의 extern_alias_directive해당 컴파일 단위의 using_directive, global_attributesnamespace_member_declaration영향을 주지만 다른 컴파일 단위에는 영향을 주지 않습니다.

컴파일 단위의 using_directive해당 컴파일 단위의 global_attributesnamespace_member_declaration영향을 주지만 다른 컴파일 단위에는 영향을 주지 않습니다.

컴파일 단위의 global_attributes(§22.3)는 대상 어셈블리 및 모듈에 대한 특성의 사양을 허용합니다. 어셈블리와 모듈은 형식에 대한 실제 컨테이너 역할을 합니다. 어셈블리는 물리적으로 분리된 여러 모듈로 구성될 수 있습니다.

프로그램의 각 컴파일 단위의 namespace_member_declaration멤버를 전역 네임스페이스라는 단일 선언 공간에 기여합니다.

예제:

// File A.cs:
class A {}
// File B.cs:
class B {}

두 컴파일 단위는 단일 전역 네임스페이스에 기여합니다. 이 경우 정규화된 이름과 A B2개의 클래스를 선언합니다. 두 컴파일 단위가 동일한 선언 공간에 기여하기 때문에 이름이 같은 멤버의 선언이 각각 포함된 경우 오류가 발생했습니다.

끝 예제

14.3 네임스페이스 선언

namespace_declaration 키워드 네임스페이스, 네임스페이스 이름 및 본문, 선택적으로 세미콜론으로 구성됩니다.

namespace_declaration
    : 'namespace' qualified_identifier namespace_body ';'?
    ;

qualified_identifier
    : identifier ('.' identifier)*
    ;

namespace_body
    : '{' extern_alias_directive* using_directive*
      namespace_member_declaration* '}'
    ;

namespace_declaration compilation_unit 최상위 선언 또는 다른 namespace_declaration 내의 멤버 선언으로 발생할 수 있습니다. compilation_unit 최상위 선언으로 namespace_declaration 발생하면 네임스페이스는 전역 네임스페이스의 멤버가 됩니다. 다른 namespace_declaration 내에서 namespace_declaration 발생하면 내부 네임스페이스는 외부 네임스페이스의 멤버가 됩니다. 두 경우 모두 네임스페이스의 이름은 포함하는 네임스페이스 내에서 고유해야 합니다.

네임스페이스는 암시적으로 public 사용되며 네임스페이스 선언에는 액세스 한정자를 포함할 수 없습니다.

namespace_body 내에서 선택적 using_directive다른 네임스페이스, 형식 및 멤버의 이름을 가져와 정규화된 이름이 아닌 직접 참조할 수 있도록 합니다. 선택적 namespace_member_declaration네임스페이스의 선언 공간에 멤버를 기여합니다. 모든 using_directive멤버 선언 앞에 표시됩니다.

namespace_declaration qualified_identifier 단일 식별자 또는 "." 토큰으로 구분된 식별자 시퀀스일 수 있습니다. 후자의 폼을 사용하면 프로그램에서 여러 네임스페이스 선언을 어휘적으로 중첩하지 않고 중첩된 네임스페이스를 정의할 수 있습니다.

예제:

namespace N1.N2
{
    class A {}
    class B {}
}

의미 체계는

namespace N1
{
    namespace N2
    {
        class A {}
        class B {}
    }
}

끝 예제

네임스페이스는 개방형이며 정규화된 이름이 동일한 두 네임스페이스 선언(§7.8.2)이 동일한 선언 공간(§7.3)에 기여합니다.

예제: 다음 코드에서

namespace N1.N2
{
    class A {}
}

namespace N1.N2
{
    class B {}
}

위의 두 네임스페이스 선언은 동일한 선언 공간에 기여합니다. 이 경우 정규화된 이름과 N1.N2.A N1.N2.B2개의 클래스를 선언합니다. 두 선언이 동일한 선언 공간에 기여하기 때문에 각 선언에 동일한 이름의 멤버 선언이 포함되어 있으면 오류가 발생합니다.

끝 예제

14.4 Extern 별칭 지시문

extern_alias_directive 네임스페이스의 별칭 역할을 하는 식별자를 소개합니다. 별칭이 지정된 네임스페이스의 사양은 프로그램의 소스 코드 외부에 있으며 별칭이 지정된 네임스페이스의 중첩된 네임스페이스에도 적용됩니다.

extern_alias_directive
    : 'extern' 'alias' identifier ';'
    ;

extern_alias_directive 범위는 compilation_unit 또는 namespace_body포함하는 using_directive, global_attributesnamespace_member_declaration 범위로 확장됩니다.

extern_alias_directive 포함하는 컴파일 단위 또는 네임스페이스 본문 내에서 extern_alias_directive 도입된 식별자를 사용하여 별칭이 지정된 네임스페이스를 참조할 수 있습니다. 식별자가 단어global인 것은 컴파일 시간 오류입니다.

extern_alias_directive 도입된 별칭은 using_alias_directive 도입된 별칭과 매우 유사합니다. extern_alias_directive 및 using_alias_directive 대한 자세한 내용은 §14.5.2를 참조하세요.

alias는 컨텍스트 키워드(§6.4.4)이며 extern_alias_directive 키워드 바로 뒤에 extern 있을 때만 특별한 의미를 줍니다.

프로그램에서 외부 정의가 제공되지 않는 extern 별칭을 선언하는 경우 오류가 발생합니다.

: 다음 프로그램은 두 개의 extern 별칭을 선언하고 사용하며Y, X 각각은 고유한 네임스페이스 계층의 루트를 나타냅니다.

extern alias X;
extern alias Y;

class Test
{
    X::N.A a;
    X::N.B b1;
    Y::N.B b2;
    Y::N.C c;
}

이 프로그램은 extern 별칭과 Y별칭 X 의 존재를 선언하지만 별칭의 실제 정의는 프로그램 외부에 있습니다. 이제 동일한 이름의 N.B 클래스를 네임스페이 X.N.B 스 별칭 한정 X::N.B Y::N.B자 및 Y.N.B. 끝 예제

14.5 Using 지시문

14.5.1 일반

지시문을 사용하면 다른 네임스페이스에 정의된 네임스페이스 및 형식을 쉽게 사용할 수 있습니다. 지시문을 사용하면 namespace_or_type_names(§7.8) 및 simple_names(§12.8.4)의 이름 확인 프로세스에 영향을 주지만 선언과 달리 using_directive새 멤버가 사용되는 컴파일 단위 또는 네임스페이스의 기본 선언 공간에 기여하지 않습니다.

using_directive
    : using_alias_directive
    | using_namespace_directive
    | using_static_directive    
    ;

using_alias_directive(§14.5.2)는 네임스페이스 또는 형식에 대한 별칭을 도입합니다.

using_namespace_directive(§14.5.3)는 네임스페이스의 형식 멤버를 가져옵니다.

using_static_directive(§14.5.4)는 형식의 중첩된 형식과 정적 멤버를 가져옵니다.

using_directive 범위는 즉시 포함된 컴파일 단위 또는 네임스페이스 본문의 namespace_member_declarations 확장됩니다. using_directive 범위에는 특히 피어 using_directive포함되지 않습니다. 따라서 피어 using_directive서로에 영향을 미치지 않으며, 피어 using_directive 기록되는 순서는 중요하지 않습니다. 반면, extern_alias_directive 범위에는 동일한 컴파일 단위 또는 네임스페이스 본문에 정의된 using_directive포함됩니다.

14.5.2 별칭 지시문 사용

using_alias_directive 즉시 바깥쪽 컴파일 단위 또는 네임스페이스 본문 내의 네임스페이스 또는 형식에 대한 별칭 역할을 하는 식별자를 소개합니다.

using_alias_directive
    : 'using' identifier '=' namespace_or_type_name ';'
    ;

using_alias_directive 포함하는 컴파일 단위 또는 네임스페이스 본문의 전역 특성 및 멤버 선언 내에서 using_alias_directive 도입된 식별자를 사용하여 지정된 네임스페이스 또는 형식을 참조할 수 있습니다.

예제:

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

    class B: A {}
}

위의 네임스페 A 이스의 N3 멤버 선언 내에서는 에 대한 N1.N2.A별칭이므로 클래스 N3.B 는 클래스N1.N2.A에서 파생됩니다. 별칭 R N1.N2 을 만든 다음 다음을 참조하여 동일한 효과를 얻을 수 있습니다.R.A

namespace N3
{
    using R = N1.N2;

    class B : R.A {}
}

끝 예제

extern_alias_directive 포함하는 컴파일 단위 또는 네임스페이스 본문의 using 지시문, 전역 특성 및 멤버 선언 내에서 extern_alias_directive 도입된 식별자를 사용하여 연결된 네임스페이스를 참조할 수 있습니다.

: 예:

namespace N1
{
    extern alias N2;

    class B : N2::A {}
}

위의 네임스페 N2 이스의 N1 멤버 선언 내에서 정의가 프로그램의 소스 코드 외부에 있는 일부 네임스페이스의 별칭입니다. 클래스는 클래스 N1.B N2.A에서 파생됩니다. 별칭 A N2.A 을 만든 다음 다음을 참조하여 동일한 효과를 얻을 수 있습니다.A

namespace N1
{
    extern alias N2;

    using A = N2::A;

    class B : A {}
}

끝 예제

extern_alias_directive 또는 using_alias_directive 특정 컴파일 단위 또는 네임스페이스 본문 내에서 별칭을 사용할 수 있지만 새 멤버를 기본 선언 공간에 제공하지는 않습니다. 즉, 별칭 지시문은 전이적이 아니라 컴파일 단위 또는 발생하는 네임스페이스 본문에만 영향을 줍니다.

예제: 다음 코드에서

namespace N3
{
    extern alias R1;

    using R2 = N1.N2;
}

namespace N3
{
    class B : R1::A, R2.I {} // Error, R1 and R2 unknown
}

두 번째 네임스페이스 선언에서 알 수 없도록 R1 포함된 네임스페이스 본문의 멤버 선언에만 도입 R1 R2 되고 R2 확장되는 별칭 지시문의 범위입니다. 그러나 포함하는 컴파일 단위에 별칭 지시문을 배치하면 두 네임스페이스 선언 내에서 별칭을 사용할 수 있게 됩니다.

extern alias R1;

using R2 = N1.N2;

namespace N3
{
    class B : R1::A, R2.I {}
}

namespace N3
{
    class C : R1::A, R2.I {}
}

끝 예제

compilation_unit 또는 namespace_body 각 extern_alias_directive 또는 using_alias_directive 즉시 바깥쪽 compilation_unit 또는 namespace_body 별칭 선언 공간(§7.3)에 이름을 지정합니다. 별칭 지시문의 식별자는 해당 별칭 선언 공간 내에서 고유해야 합니다. 별칭 식별자는 전역 선언 공간 또는 해당 네임스페이스의 선언 공간 내에서 고유할 필요가 없습니다.

예제:

extern alias X;
extern alias Y;

using X = N1.N2; // Error: alias X already exists

class Y {} // Ok

명명된 X using 별칭은 동일한 컴파일 단위에 이미 명명 X 된 별칭이 있으므로 오류가 발생합니다. 명명된 Y 클래스는 이러한 이름이 고유 선언 공간에 추가되기 때문에 명명된 Y extern 별칭과 충돌하지 않습니다. 전자는 전역 선언 공간에 추가되고 후자는 이 컴파일 단위의 별칭 선언 공간에 추가됩니다.

별칭 이름이 네임스페이스의 멤버 이름과 일치하는 경우 다음 중 하나를 적절하게 사용해야 합니다.

namespace N1.N2
{
    class B {}
}

namespace N3
{
    class A {}
    class B : A {}
}

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

    class W : B {} // Error: B is ambiguous
    class X : A.B {} // Error: A is ambiguous
    class Y : A::B {} // Ok: uses N1.N2.B
    class Z : N3.B {} // Ok: uses N3.B
}

두 번째 네임스페이스 본문 N3B 에서는 이름이 지정된 B 멤버와 이름을 AB가진 별칭을 선언하는 네임스페이스 본문이 포함되어 있으므로 오류가 발생 N3 합니다. 클래스 N3.B 를 참조할 수 있습니다.N3.B global::N3.B 별칭 A 은 정규화된 별칭 멤버(§14.8)에서 A::B사용할 수 있습니다. 별칭 B 은 본질적으로 쓸모가 없습니다. qualified_alias_member 네임스페이스 별칭만 사용하고 형식을 별칭화할 수 있으므로 qualified_alias_member B 사용할 수 없습니다.

끝 예제

일반 멤버와 마찬가지로 alias_directives 도입된 이름은 중첩된 범위에서 비슷하게 명명된 멤버에 의해 숨겨집니다.

예제: 다음 코드에서

using R = N1.N2;

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

선언 B 에서 참조 R.A 하면 컴파일 시간 오류가 R 발생합니다.N3.RN1.N2

끝 예제

extern_alias_directive기록되는 순서는 의미가 없습니다. 마찬가지로, using_alias_directive 기록되는 순서는 의미가 없지만 모든 using_alias_directives 동일한 컴파일 단위 또는 네임스페이스 본문에 있는 모든 extern_alias_directive후에 나옵니다. using_alias_directive 참조하는 namespace_or_type_name 확인은 즉시 포함된 컴파일 단위 또는 네임스페이스 본문의 using_alias_directive 자체 또는 다른 using_directive영향을 받지 않지만 즉시 포함된 컴파일 단위 또는 네임스페이스 본문의 extern_alias_directive영향을 받을 수 있습니다. 즉, 즉시 포함된 컴파일 단위 또는 네임스페이스 본문에 using_directive 없지만 올바른 extern_alias_directive 집합이 있는 것처럼 using_alias_directivenamespace_or_type_name확인됩니다.

예제: 다음 코드에서

namespace N1.N2 {}

namespace N3
{
    extern alias X;

    using R1 = X::N; // OK
    using R2 = N1; // OK
    using R3 = N1.N2; // OK
    using R4 = R2.N2; // Error, R2 unknown
}

마지막 using_alias_directive 이전 using_alias_directive 영향을 받지 않으므로 컴파일 시간 오류가 발생합니다. x 외래 별칭의 범위에 using_alias_directive 포함되므로 첫 번째 using_alias_directive 오류가 발생하지 않습니다.

끝 예제

using_alias_directive 표시되는 네임스페이스 및 해당 네임스페이스 내에 중첩된 네임스페이스 또는 형식을 포함하여 모든 네임스페이스 또는 형식에 대한 별칭을 만들 수 있습니다.

별칭을 통해 네임스페이스 또는 형식에 액세스하면 선언된 이름을 통해 해당 네임스페이스 또는 형식에 액세스하는 것과 정확히 동일한 결과가 생성됩니다.

: 지정

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.A동일 R1.N2.A하며 R2.A 모두 정규화된 이름이 있는 클래스 선언을 참조합니다 N1.N2.A.

끝 예제

부분 형식의 각 부분(§15.2.7)은 동일한 네임스페이스 내에서 선언되지만 일반적으로 파트는 서로 다른 네임스페이스 선언 내에 기록됩니다. 따라서 각 부분에 대해 서로 다른 extern_alias_directiveusing_directive존재할 수 있습니다. 한 부분 내에서 단순 이름(§12.8.4)을 해석하는 경우 해당 부분을 둘러싸는 네임스페이스 본문 및 컴파일 단위의 extern_alias_directive 및 using_directive고려됩니다. 이로 인해 동일한 식별자가 서로 다른 부분에서 다른 의미를 가질 수 있습니다.

예제:

namespace N
{
    using List = System.Collections.ArrayList;

    partial class A
    {
        List x; // x has type System.Collections.ArrayList
    }
}

namespace N
{
    using List = Widgets.LinkedList;

    partial class A
    {
        List y; // y has type Widgets.LinkedList
    }
}

끝 예제

별칭을 사용하면 닫힌 생성된 형식의 이름을 지정할 수 있지만 형식 인수를 제공하지 않고는 바인딩되지 않은 제네릭 형식 선언의 이름을 지정할 수 없습니다.

예제:

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
}

끝 예제

14.5.3 네임스페이스 지시문 사용

using_namespace_directive 네임스페이스에 포함된 형식을 즉시 바깥쪽 컴파일 단위 또는 네임스페이스 본문으로 가져와 각 형식의 식별자를 정규화 없이 사용할 수 있도록 합니다.

using_namespace_directive
    : 'using' namespace_name ';'
    ;

using_namespace_directive 포함하는 컴파일 단위 또는 네임스페이스 본문의 멤버 선언 내에서 지정된 네임스페이스에 포함된 형식을 직접 참조할 수 있습니다.

예제:

namespace N1.N2
{
    class A {}
}

namespace N3
{
    using N1.N2;

    class B : A {}
}

위의 네임스페이스의 N3 멤버 선언 내에서 형식 멤버를 N1.N2 직접 사용할 수 있으므로 클래스 N3.B 는 클래스 N1.N2.A에서 파생됩니다.

끝 예제

using_namespace_directive 지정된 네임스페이스에 포함된 형식을 가져오지만 특히 중첩된 네임스페이스를 가져오지는 않습니다.

예제: 다음 코드에서

namespace N1.N2
{
    class A {}
}

namespace N3
{
    using N1;
    class B : N2.A {} // Error, N2 unknown
}

using_namespace_directive 에 포함된 N1형식을 가져오지만 중첩된 N1네임스페이스는 가져옵니다. 따라서 이름이 B 지정된 N2 멤버가 없기 때문에 선언에서 참조 N2.A 하면 컴파일 시간 오류가 발생합니다.

끝 예제

using_alias_directive 달리 using_namespace_directive 바깥쪽 컴파일 단위 또는 네임스페이스 본문 내에서 식별자가 이미 정의된 형식을 가져올 수 있습니다. 실제로 using_namespace_directive 가져온 이름은 바깥쪽 컴파일 단위 또는 네임스페이스 본문에서 비슷한 이름의 멤버에 의해 숨겨집니다.

예제:

namespace N1.N2
{
    class A {}
    class B {}
}

namespace N3
{
    using N1.N2;
    class A {}
}

여기서 네임스페 A N3.A N1.N2.A이스의 N3 멤버 선언 내에서는 .

끝 예제

가져온 네임스페이스가 두 개 이상 동일한 형식 이름을 도입하는 경우 이름이 모호할 수 있으므로 using_alias_directive 참조를 명확하게 하는 데 유용합니다.

예제: 다음 코드에서

namespace N1
{
    class A {}
}

namespace N2
{
    class A {}
}

namespace N3
{
    using N1;
    using N2;

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

둘 다 N1 멤버 N2 A를 포함하며 둘 다 가져오기 때문에 N3 참조는 A N3 컴파일 시간 오류입니다. 이 경우 참조A의 자격 또는 특정A을 선택하는 using_alias_directive 도입하여 충돌을 해결할 수 있습니다. 예시:

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

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

끝 예제

또한 동일한 컴파일 단위 또는 네임스페이스 본문에 using_namespace_directive 또는 using_static_directive 가져온 두 개 이상의 네임스페이스 또는 형식이 동일한 이름의 형식 또는 멤버를 포함하는 경우 simple_name 해당 이름에 대한 참조는 모호한 것으로간주됩니다.

예제:

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 simple_name 참조하는 A 것이 모호하고 컴파일 시간 오류가 발생합니다.

끝 예제

using_alias_directive 마찬가지로 using_namespace_directive 컴파일 단위 또는 네임스페이스의 기본 선언 공간에 새 멤버를 제공하지 않고 표시되는 컴파일 단위 또는 네임스페이스 본문에만 영향을 줍니다.

using_namespace_directive 참조하는 namespace_name using_alias_directive 참조하는 namespace_or_type_name 동일한 방식으로 확인됩니다. 따라서 동일한 컴파일 단위 또는 네임스페이스 본문에 있는 using_namespace_directive서로에 영향을 주지 않으며 순서대로 작성할 수 있습니다.

14.5.4 정적 지시문 사용

using_static_directive 형식 선언에 직접 포함된 중첩된 형식 및 정적 멤버를 즉시 바깥쪽 컴파일 단위 또는 네임스페이스 본문으로 가져와서 각 멤버 및 형식의 식별자를 정규화 없이 사용할 수 있도록 합니다.

using_static_directive
    : 'using' 'static' type_name ';'
    ;

using_static_directive 포함하는 컴파일 단위 또는 네임스페이스 본문의 멤버 선언 내에서 지정된 형식의 선언에 직접 포함된 액세스 가능한 중첩 형식 및 정적 멤버(확장 메서드 제외)를 직접 참조할 수 있습니다.

예제:

namespace N1
{
   class A 
   {
        public class B {}
        public static B M() => new B();
   }
}

namespace N2
{
    using static N1.A;

    class C
    {
        void N()
        {
            B b = M();
        }
    }
}

앞의 코드에서 네임스페이스의 N2 멤버 선언 내에서 정적 멤버와 중첩 형식을 N1.A 직접 사용할 수 있으므로 메서드는 해당 멤버 NM 멤버N1.A를 모두 B 참조할 수 있습니다.

끝 예제

using_static_directive 특히 확장 메서드를 정적 메서드로 직접 가져오지는 않지만 확장 메서드 호출(§12.8.9.3)에 사용할 수 있습니다.

예제:

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 포함된 N1.A확장 메서드를 확장 메서드 M 로만 가져옵니다. 따라서 이름이 지정된 M 멤버가 없으므로 결과 본문에 B.N 대한 첫 번째 참조 M 는 컴파일 시간 오류가 발생합니다.

끝 예제

using_static_directive 기본 클래스에 선언된 멤버 및 형식이 아니라 지정된 형식에서 직접 선언된 멤버 및 형식만 가져옵니다.

예제:

namespace N1 
{
    class A 
    {
        public static void M(string s){}
    }

    class B : A
    {
        public static void M2(string s){}
    }
}

namespace N2
{
    using static N1.B;

    class C
    {
        void N()
        {
            M2("B");      // OK, calls B.M2
            M("C");       // Error. M unknown 
        }
    }
}

using_static_directive 포함된 N1.B메서드 M2 를 가져오지만 포함된 메서드 M N1.A는 가져오지 않습니다. 따라서 이름이 지정된 M 멤버가 없으므로 결과 본문 C.N 에 대한 참조 M 는 컴파일 시간 오류가 발생합니다. 개발자는 두 번째 using static 지시문을 추가하여 메서드 N1.A 도 가져와야 함을 지정해야 합니다.

끝 예제

여러 using_namespace_directives using_static_directives 간의 모호성은 §14.5.3에서 설명합니다.

14.6 네임스페이스 멤버 선언

namespace_member_declaration namespace_declaration(§14.3) 또는 type_declaration(§14.7)입니다.

namespace_member_declaration
    : namespace_declaration
    | type_declaration
    ;

컴파일 단위 또는 네임스페이스 본문은 namespace_member_declaration포함할 수 있으며, 이러한 선언은 포함하는 컴파일 단위 또는 네임스페이스 본문의 기본 선언 공간에 새 멤버를 제공합니다.

14.7 형식 선언

type_declaration class_declaration(§15.2), struct_declaration(§16.2), interface_declaration(§18.2), enum_declaration(§19.2) 또는 delegate_declaration(§20.2)입니다.

type_declaration
    : class_declaration
    | struct_declaration
    | interface_declaration
    | enum_declaration
    | delegate_declaration
    ;

type_declaration 컴파일 단위의 최상위 선언 또는 네임스페이스, 클래스 또는 구조체 내의 멤버 선언으로 발생할 수 있습니다.

형식에 대한 형식 T 선언이 컴파일 단위에서 최상위 선언으로 발생하는 경우 형식 선언의 정규화된 이름(§7.8.2)은 선언의 정규화되지 않은 이름(§7.8.2)과 동일합니다. 형식에 대한 형식 T 선언이 네임스페이스, 클래스 또는 구조체 선언 내에서 발생하는 경우 형식 선언의 정규화된 이름(§7.8.3)이며, 포함하는 S 네임스페이스S.N, 클래스 또는 구조체 선언의 정규화된 이름이며 N 선언의 정규화되지 않은 이름입니다.

클래스 또는 구조체 내에서 선언된 형식을 중첩 형식(§15.3.9)이라고 합니다.

형식 선언에 허용되는 액세스 한정자와 기본 액세스는 선언이 발생하는 컨텍스트(§7.5.2)에 따라 달라집니다.

  • 컴파일 단위 또는 네임스페이스에 선언된 형식은 사용 public 하거나 internal 액세스할 수 있습니다. 기본값은 액세스입니다 internal .
  • 클래스에 선언된 형식에는 , , protected internalprotected, private protectedinternal또는 private 액세스 권한이 있을 public수 있습니다. 기본값은 액세스입니다 private .
  • 구조체에 선언된 형식에는 액세스 권한이 있거나 private 액세스할 수 있습니다.publicinternal 기본값은 액세스입니다 private .

14.8 정규화된 별칭 멤버

14.8.1 일반

네임스페이스 별칭 한정 :: 자를 사용하면 형식 이름 조회가 새 형식 및 멤버의 도입에 영향을 받지 않도록 보장할 수 있습니다. 네임스페이스 별칭 한정자는 항상 왼쪽 및 오른쪽 식별자라고 하는 두 식별자 사이에 나타납니다. 일반 . 한정자와 달리 한정자의 :: 왼쪽 식별자는 extern 또는 사용 별칭으로만 조회됩니다.

qualified_alias_member 전역 네임스페이스에 대한 명시적 액세스를 제공하고 다른 엔터티에 의해 잠재적으로 숨겨질 수 있는 별칭을 익히거나 사용할 수 있습니다.

qualified_alias_member
    : identifier '::' identifier type_argument_list?
    ;

qualified_alias_member namespace_or_type_name(§7.8) 또는 member_access 왼쪽 피연산자로 사용할 수 있습니다(§12.8.7).

qualified_alias_member 왼쪽 및 오른쪽 식별자라고 하는 두 개의 식별자로 구성되며, 토큰으로 :: 구분되고 필요에 따라 type_argument_list. 왼쪽 식별자가 전역이면 전역 네임스페이스가 오른쪽 식별자를 검색합니다. 다른 왼쪽 식별자의 경우 해당 식별자는 extern 또는 별칭(§14.4§14.5.2)을 사용하여 조회됩니다. 이러한 별칭이 없거나 별칭이 형식을 참조하는 경우 컴파일 시간 오류가 발생합니다. 별칭이 네임스페이스를 참조하는 경우 해당 네임스페이스는 오른쪽 식별자를 검색합니다.

qualified_alias_member 다음 두 가지 형식 중 하나입니다.

  • N::I<A₁, ..., Aₑ>- 식별자를 나타내 NI <A₁, ..., Aₑ> 형식 인수 목록입니다. (e 항상 하나 이상입니다.)
  • N::I, 식별자 및 N I 식별자를 나타냅니다. (이 경우 e 0으로 간주됩니다.)

이 표기법을 사용하여 qualified_alias_member 의미는 다음과 같이 결정됩니다.

  • 식별자인 경우 N 전역 네임스페이스가 다음을 검색합니다I.global
    • 전역 네임스페이스에 이름이 0이고 eI 임스페이스가 0이면 qualified_alias_member 해당 네임스페이스를 참조합니다.
    • 그렇지 않은 경우 전역 네임스페이스에 이름이 제 I 네릭이 아닌 형식이 포함되어 있고 e 0 이면 qualified_alias_member 해당 형식을 참조합니다.
    • 그렇지 않으면 전역 네임스페이스에 형식 매개 변수가 있는 형식 Ie 포함된 경우 qualified_alias_member 지정된 형식 인수로 생성된 해당 형식을 참조합니다.
    • 그렇지 않으면 qualified_alias_member 정의되지 않고 컴파일 시간 오류가 발생합니다.
  • 그렇지 않은 경우 즉시 qualified_alias_member 포함하는 네임스페이스 선언(§14.3)부터 시작하여 각 바깥쪽 네임스페이스 선언(있는 경우)을 계속 진행하며, qualified_alias_member 포함하는 컴파일 단위로 끝나는 경우 엔터티가 배치될 때까지 다음 단계가 평가됩니다.
    • 네임스페이스 선언 또는 컴파일 단위에 N을 형식과 연결하는 using_alias_directive 포함된 경우 qualified_alias_member 정의되지 않고 컴파일 시간 오류가 발생합니다.
    • 그렇지 않은 경우 네임스페이스 선언 또는 컴파일 단위에 네임스페이스와 연결된 N extern_alias_directive 또는 using_alias_directive 포함되어 있으면 다음을 수행합니다.
      • 연결된 N 네임스페이스에 이름이 0이고 eI 임스페이스가 0이면 qualified_alias_member 해당 네임스페이스를 참조합니다.
      • 그렇지 않은 경우 연결된 N 네임스페이스에 이름이 제 I 네릭이 아닌 형식이 포함되어 있고 e 0 이면 qualified_alias_member 해당 형식을 참조합니다.
      • 그렇지 않은 경우 연결된 네임스페이스에 형식 매개 변수가 있는 명명 IN 형식이 e 포함된 경우 qualified_alias_member 지정된 형식 인수로 생성된 해당 형식을 참조합니다.
      • 그렇지 않으면 qualified_alias_member 정의되지 않고 컴파일 시간 오류가 발생합니다.
  • 그렇지 않으면 qualified_alias_member 정의되지 않고 컴파일 시간 오류가 발생합니다.

예제: 코드에서:

using S = System.Net.Sockets;

class A
{
    public static int x;
}

class C
{
    public void F(int A, object S)
    {
        // Use global::A.x instead of A.x
        global::A.x += A;
        // Use S::Socket instead of S.Socket
        S::Socket s = S as S::Socket;
    }
}

클래스 A 가 참조 global::A 되고 형식 System.Net.Sockets.Socket 이 .로 참조됩니다 S::Socket. 매개 변수를 S.Socket 사용하여 A.x 해결했으므로 대신 컴파일 시간 오류를 A S 발생시켰을 것입니다.

끝 예제

참고: 식별자는 global qualified_alias_name 왼쪽 식별자로 사용되는 경우에만 특별한 의미가 있습니다. 키워드가 아니며 그 자체가 별칭이 아닙니다. 컨텍스트 키워드(§6.4.4)입니다. 코드에서:

class A { }

class C
{
    global.A x; // Error: global is not defined
    global::A y; // Valid: References A in the global namespace
}

을 사용하면 global.A 범위에 명명 global 된 엔터티가 없으므로 컴파일 시간 오류가 발생합니다. Global이라는 일부 엔터티가 범위에 global 있는 경우 해당 엔터티로 global.A 확인되었을 것입니다.

qualified_alias_member 왼쪽 식별자로 사용하면 global 명명global된 using 별칭이 있더라도 항상 네임스페이스에서 조회 global 가 발생합니다. 코드에서:

using global = MyGlobalTypes;

class A { }

class C 
{
    global.A x; // Valid: References MyGlobalTypes.A
    global::A y; // Valid: References A in the global namespace
}

global.AMyGlobalTypes.A global::A 전역 네임스페이스의 클래스 A 로 확인됩니다.

끝 메모

14.8.2 별칭의 고유성

각 컴파일 단위 및 네임스페이스 본문에는 외래 별칭 및 별칭을 사용하는 별도의 선언 공간이 있습니다. 따라서 extern 별칭 또는 사용 별칭의 이름은 extern 별칭 집합 내에서 고유해야 하며 즉시 포함하는 컴파일 단위 또는 네임스페이스 본문에 선언된 별칭을 사용하는 반면, 한정자와만 :: 사용되는 한 별칭은 형식 또는 네임스페이스와 동일한 이름을 가질 수 있습니다.

: 다음에서:

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 와 using 별칭이 모두 범위에 있으므로 두 번째 네임스페이스 A 본문에는 두 가지 의미가 있습니다. 이러한 이유로 정규화된 이름 A.Stream 에서 사용하는 A 것은 모호하며 컴파일 시간 오류가 발생합니다. 그러나 한정자를 :: 사용하는 A 것은 네임스페이스 별칭으로만 조회되므로 오류가 A 아닙니다.

끝 예제