`namespace` 키워드

namespace 키워드

서로 관련된 객체들을 한데 묶어 둘 공간이 필요할 때가 있어요. namespace 키워드로 그런 스코프를 선언하면, 코드 요소를 정리할 수 있고 전역에서 유일한 타입을 만들 수도 있어요. 말 그대로 이름 공간이라서, 같은 이름의 타입이라도 서로 다른 네임스페이스 안에 있으면 충돌 없이 공존할 수 있죠.

출처: The namespace keyword

본문

네임스페이스 안에는 클래스, 인터페이스 같은 타입들이 들어갑니다. 그 형태를 먼저 볼게요.

namespace SampleNamespace
{
    class SampleClass { }

    interface ISampleInterface { }

    struct SampleStruct { }

    enum SampleEnum { a, b }

    delegate void SampleDelegate(int i);

    namespace Nested
    {
        class SampleClass2 { }
    }
}

이때 파일 안에 있는 모든 타입을 단 하나의 네임스페이스에 두고 싶다면, 중괄호 대신 세미콜론(;)으로 끝내는 파일-스코프 네임스페이스 선언을 쓸 수 있어요. C# 10에서 도입된 기능인데, 앞 예제와 같은 내용을 훨씬 간결하게 적을 수 있죠.

using System;

namespace SampleFileScopedNamespace;

class SampleClass { }

interface ISampleInterface { }

struct SampleStruct { }

enum SampleEnum { a, b }

delegate void SampleDelegate(int i);

파일-스코프 네임스페이스에서의 using 문

파일-스코프 네임스페이스를 쓰면 using 문을 어디에 두느냐에 따라 그 적용 범위가 달라져요. 컴파일러는 내부적으로 파일-스코프 네임스페이스를 파일 끝에 닫는 중괄호가 붙은 전통적인 네임스페이스 선언으로 바꿔서 처리한다는 점을 기억하면 규칙이 자연스럽게 이해돼요.

  • 파일-스코프 네임스페이스 선언 에 둔 using은 네임스페이스 밖에 있는 것으로 취급되어 전역에 적용돼요.
  • 파일-스코프 네임스페이스 선언 에 둔 using은 그 네임스페이스 안으로 범위가 제한돼요.

예시로 확인해 볼게요.

// This using is outside the namespace scope, so it applies globally
using System;

namespace SampleNamespace; // File-scoped namespace declaration

// This using is inside the namespace scope
using System.Text;

public class SampleClass
{
    // Class members...
}

위 예제에서 System은 어디서든 쓸 수 있는 반면, System.TextSampleNamespace 안에서만 적용돼요.

그런데 파일-스코프 네임스페이스는 중첩 네임스페이스를 포함할 수 없어요. 두 번째 파일-스코프 네임스페이스를 선언하거나, 그 안에 중첩 네임스페이스를 새로 선언하는 건 허용되지 않죠.

namespace SampleNamespace;

class AnotherSampleClass
{
    public void AnotherSampleMethod()
    {
        System.Console.WriteLine(
            "SampleMethod inside SampleNamespace");
    }
}

namespace AnotherNamespace; // Not allowed!

namespace ANestedNamespace // Not allowed!
{
   // declarations...
}

네임스페이스 안에는 다음 타입들을 0개 이상 선언할 수 있어요.

컴파일러는 기본적으로 기본 네임스페이스(global namespace, 전역 네임스페이스라고도 불러요)를 하나 만들어 넣습니다. 이 이름 없는 네임스페이스는 모든 파일에 존재하고, 어떤 선언된 네임스페이스에도 속하지 않는 선언들을 담게 돼요. 전역 네임스페이스에 있는 식별자는 어떤 이름 있는 네임스페이스에서든 그대로 쓸 수 있어요.

네임스페이스는 기본적으로 public 접근 권한을 가집니다. 네임스페이스 안 요소에 어떤 접근 한정자를 붙일 수 있는지는 Access Modifiers에서 다뤄요.

하나의 네임스페이스를 두 번 이상 나누어 정의하는 것도 가능해요. 아래 예시는 MyCompany 네임스페이스의 일부로 클래스 두 개를 정의하고 있죠. 나중에 같은 네임스페이스 이름으로 다시 열어 타입을 추가하면 같은 네임스페이스에 합쳐져요.

namespace MyCompany.Proj1
{
    class MyClass
    {
    }
}

namespace MyCompany.Proj1
{
    class MyClass1
    {
    }
}

중첩 네임스페이스 안의 정적 메서드를 호출하는 모습도 볼게요.

namespace SomeNameSpace
{
    public class MyClass
    {
        static void Main()
        {
            Nested.NestedNameSpaceClass.SayHello();
        }
    }

    // a nested namespace
    namespace Nested
    {
        public class NestedNameSpaceClass
        {
            public static void SayHello()
            {
                Console.WriteLine("Hello");
            }
        }
    }
}
// Output: Hello

더 알아보기