33. 네임스페이스(Namespace)
지금까지 닷넷에서 제공해주는 API를 통해서 네임스페이스(namespace)를 여러 번 사용해 보았습니다. 닷넷에는 System
, System.Text
, System.Linq
, System.Generic
등 많은 네임스페이스를 제공합니다. 이번 강의에서는 이러한 네임스페이스를 직접 만들어 보겠습니다.
> // 네임스페이스: 클래스 등의 사용자 정의 형식의 이름 충돌 방지 및 관련 기능끼리 묶어서 관리
33.1. 네임스페이스
네임스페이스는 프로그램이 커질 때 클래스 이름 충돌을 방지하기 위해 클래스를 모아서 관리하는 개념입니다. 이는 인터넷 도메인 주소를 사용하여 각각의 사이트를 유일하게 식별하는 것과 같은 방식으로, 동일한 이름의 클래스를 네임스페이스를 다르게 함으로써 하나의 프로젝트에서 사용할 수 있도록 합니다.
그림: 네임스페이스로 클래스 묶어서 관리
닷넷에는 수많은 클래스들이 존재합니다. 이러한 클래스들은 같은 의미를 갖는 클래스끼리 네임스페이스로 묶어서 관리합니다. 우리가 지금까지 사용해오던 Console
클래스와 같이 주요 클래스들은 System
네임스페이스 안에 선언되어 사용해 왔습니다. 지금까지 해왔던 것처럼 이러한 네임스페이스는 using
지시문을 사용하여 클래스 파일의 상단에 선언 후 사용합니다.
네임스페이스는 다음과 같은 특징이 있습니다. 간단히 읽어보고 넘어가면 됩니다.
- 서로 관련 있는 클래스, 구조체, 열거형 등의 형식과 또 다른 네임스페이스 등을 묶어서 관리해주는 개념입니다.
- 클래스의 이름이 중복되는 것을 방지하는 역할을 합니다.
- 클래스를 계층형으로 묶어서 관리할 수 있습니다.
- 네임스페이스는 패키지란 단어와 비슷한 의미를 가지는 관련 있는 형식들의 묶음입니다.
33.1.1. 클래스 이름 충돌
그렇다면 네임스페이스는 왜 사용할까요? 하나의 큰 프로젝트를 개발하다 보면, A 개발자도 Car
이름의 클래스를 만들고 동시에 B 개발자도 Car
이름의 클래스를 만들 수 있습니다. 이때 클래스 이름이 같아 충돌이 발생합니다. 이러한 경우에는 네임스페이스를 사용하여 서로 관련 있는 클래스끼리 구분해 묶어서 관리하면 됩니다.
33.2. 네임스페이스 만들기
C#에서 네임스페이스를 만들려면 namespace
키워드를 사용합니다.
33.2.1. 네임스페이스 정의
네임스페이스는 다음과 같이 namespace
키워드 뒤에 네임스페이스의 이름을 지정해서 사용합니다. 네임스페이스 이름도 클래스 이름과 마찬가지로 대문자로 시작합니다.
namespace 네임스페이스이름
{
// 클래스 등의 정의가 들어옴
}
MyCar
라는 네임스페이스를 만들고 이곳에 Car
라는 클래스를 만드는 구문은 다음과 같습니다.
namespace MyCar
{
public class Car
{
// Car 클래스의 내용 구현
}
}
네임스페이스는 여러 번 계층형으로 구분해서 사용할 수 있습니다. 각각의 네임스페이스 안에는 클래스 정의 코드가 들어올 수 있습니다.
namespace AllCar
{
namespace MyCar { }
namespace YourCar { }
}
앞과 같은 네임스페이스 중첩 구문은 다음과 같이 마침표 구문을 사용하여 표현할 수도 있습니다.
namespace AllCar.MyCar { }
namespace AllCar.YourCar { }
네임스페이스: 이름 충돌 방지 및 관련 기능끼리 묶어서 관리
네임스페이스를 사용하여 같은 이름의 클래스를 구분해 보겠습니다.
코드: NamespaceNote.cs
//[?] 네임스페이스: 클래스 등의 사용자 정의 형식의 이름 충돌 방지 및 관련 기능끼리 묶어서 관리
using System;
namespace Foo
{
public class Car
{
public void Go() => Console.WriteLine("[1] Foo 네임스페이스의 Car 클래스 호출");
}
}
namespace Bar
{
public class Car
{
public void Go() => Console.WriteLine("[2] Bar 네임스페이스의 Car 클래스 호출");
}
}
class NamespaceNote
{
static void Main()
{
Foo.Car fooCar = new Foo.Car();
fooCar.Go(); // [1] Foo 네임스페이스의 Car 클래스 호출
Bar.Car barCar = new Bar.Car();
barCar.Go(); // [2] Bar 네임스페이스의 Car 클래스 호출
}
}
[1] Foo 네임스페이스의 Car 클래스 호출
[2] Bar 네임스페이스의 Car 클래스 호출
프로그램의 규모가 커짐에 따라 클래스 이름이 동일하여 충돌이 발생할 수도 있습니다. Foo
라는 회사 또는 개발자가 Car
클래스를 설계하였는데, Bar
라는 회사 또는 개발자도 Car
클래스를 설계하는 경우에, 이를 하나의 프로젝트로 합쳤을 경우 클래스 이름이 동일하여 충돌이 발생합니다. 이때는 도메인 이름 또는 제품 이름으로 네임스페이스를 만들어 클래스를 감싸주면 이름 충돌이 발생하지 않습니다.
네임스페이스가 적용된 클래스를 호출할 때는 네임스페이스.클래스
형태를 사용하면 됩니다.
닷넷 코어 또는 닷넷 프레임워크에 내장되어 있는 모든 클래스는 특정 네임스페이스에 속해 있는 것처럼 클래스를 처음 설계할 때부터 네임스페이스를 함께 고민해서 만들어야 합니다.
이 강의에서는 지면 절약을 위해서 하나의 파일에 Foo.Car
클래스, Bar.Car
클래스 NamespaceNote
클래스의 3가지 클래스 코드를 작성하였습니다. 실제로 프로그램을 작성할 때는 각 클래스를 다른 파일로 관리하는 것이 더 권장되는 방법입니다.
33.3. using
지시문
namespace
키워드를 사용해 만든 네임스페이스를 특정 C# 파일에서 사용하려면 코드 상단에 using
지시문을 사용하여 해당 네임스페이스를 현재 파일에서 사용하겠다고 선언할 수 있습니다.
우리가 지금까지 익히 사용해 오던 using
키워드를 사용하여 다음 구문과 동일하게 네임스페이스 이름을 지정하면 됩니다.
using System; // System 네임스페이스를 현재 CS 파일 또는 네임스페이스에서 사용하겠다고 지정
using MyNamespace; // MyNamespace 네임스페이스를 현재 CS 파일에서 사용하겠다고 지정
using AllCar.MyCar; // 계층형 네임스페이스를 지정
당연한 얘기겠지만, using
지시문을 사용하지 않고 전체 네임스페이스와 클래스 이름을 함께 사용해도 무관합니다.
AllCar.MyCar.Car car = new AllCar.MyCar.Car();
네임스페이스를 참조하기 위한 using
키워드는 일반적으로 CS 파일 상단에 지정하고 특정 네임스페이스안에 둘 수도 있습니다.
33.3.1. 네임스페이스 선언과 사용
이번에는 네임스페이스를 선언하고 사용하는 또 다른 방법을 알아보겠습니다.
코드: NamespaceDescription.cs
using Korea.Seoul; // Korea.Seoul 네임스페이스의 클래스를 바로 사용 가능
using System;
using In = Korea.Incheon; // Korea.Incheon 네임스페이스를 In 네임스페이스로 별칭 붙여 사용
namespace Korea
{
namespace Seoul
{
public class Car
{
public void Run() => Console.WriteLine("서울 자동차가 달립니다.");
}
}
namespace Incheon
{
public class Car
{
public void Run() => Console.WriteLine("인천 자동차가 달립니다.");
}
}
}
namespace NamespaceDescription
{
class NamespaceDescription
{
static void Main()
{
//[1] 네임스페이스 전체 지정
Korea.Seoul.Car s = new Korea.Seoul.Car();
s.Run(); // 서울
Korea.Incheon.Car i = new Korea.Incheon.Car();
i.Run(); // 인천
//[2] 네임스페이스 선언부에 선언
Car seoul = new Car();
seoul.Run(); // 서울
//[3] 별칭을 사용해서 간결하게 사용
In.Car ic = new In.Car();
ic.Run(); // 인천
}
}
}
서울 자동차가 달립니다.
인천 자동차가 달립니다.
서울 자동차가 달립니다.
인천 자동차가 달립니다.
[1]
번 코드처럼 서로 다른 Car
클래스를 한 곳에서 사용하고자 할 때는 직접 네임스페이스 전체 이름을 지정해서 인스턴스를 생성해야 합니다.
[2]
번 코드는 만약, 하나의 네임스페이스만 코드 상단에 using 지시문
으로 선언해 두었으면 해당 클래스는 네임스페이스를 생략한 채 사용할 수 있습니다.
[3]
번 코드처럼 using 지시문
에서 Korea.Incheon
네임스페이스를 In
이름의 별칭으로 선언하고 이를 통해 코드내에서 줄여서 표현하는 방법도 제공합니다. 참고로 이러한 방법을 using
을 사용한 사용자 정의 데이터 형식 구현이라고 합니다.
33.3.2. using
을 사용한 사용자 정의 데이터 형식 구현
이번에는 using
을 사용하여 사용자 정의 데이터 형식을 구현하는 방법을 알아보겠습니다.
코드: TypeDefinitionWithUsing.cs
//[I] 네임스페이스 추가
using System;
namespace TypeDefinitionWithUsing
{
//[II] Gilbut.Education.CSharp.Lecture 형식을 Project 별칭으로 줄여서 사용
using Project = Gilbut.Education.CSharp.Lecture;
public class TypeDefinitionWithUsing
{
public static void Main(string[] args)
{
//[1] 기본 호출
Gilbut.Education.CSharp.Lecture l =
new Gilbut.Education.CSharp.Lecture();
Console.WriteLine(l);
//[2] using 지시문 사용 호출
Project p = new Project();
Console.WriteLine(p);
}
}
}
namespace Gilbut
{
namespace Education
{
namespace CSharp
{
public class Lecture
{
public override string ToString()
{
return "Lecture 클래스 호출됨";
}
}
}
}
}
Lecture 클래스 호출됨
Lecture 클래스 호출됨
[1]
번 코드처럼 기본적인 방법을 사용하여 네임스페이스의 클래스를 호출하는 방법과 [2]
번 코드처럼 새로운 별칭을 만들고 코드내에서 줄여서 사용하는 방법 중 원하는 방법을 통해서 클래스의 인스턴스를 생성할 수 있습니다.
파일 범위 네임스페이스
C# 10에서는 파일 범위 네임스페이스(File-Scoped Namespace)C# 10라는 편의 기능이 도입되었습니다. 이 기능을 통해 네임스페이스를 선언할 때 중괄호를 제거할 수 있어 코드가 더 간결해집니다.
기존 방식 (C# 1.0 ~ C# 9.0)
C# 1.0부터 9.0까지는 네임스페이스를 반드시 중괄호({}
)로 열고 닫아야 했습니다. 하지만 대부분의 개발자가 하나의 .cs
파일에 하나의 네임스페이스만 사용하는 경향이 있기 때문에, 불필요한 중괄호와 들여쓰기를 줄이기 위한 개선이 필요했습니다.
전통적인 네임스페이스 선언 방식
namespace X.Y.Z
{
// usings
// types
}
// usings
namespace X.Y.Z
{
// types
}
파일 범위 네임스페이스 (C# 10 이상)
C# 10부터는 파일 범위 네임스페이스를 사용해 네임스페이스 선언을 간단히 할 수 있습니다. 이 방식에서는 중괄호를 없애고 세미콜론(;
)으로 선언을 마칩니다. 클래스와 같은 형식에만 집중할 수 있어 코드 가독성이 향상됩니다. 다른 언어 사용자에게도 더 친숙하게 느껴질 수 있습니다.
파일 범위 네임스페이스 예시
namespace X.Y.Z;
using System;
class X
{
}
Visual Studio에서 파일 범위 네임스페이스로 변환하기
Visual Studio를 사용하면 기존의 네임스페이스 선언을 파일 범위 네임스페이스로 간편하게 변환할 수 있습니다.
기존 네임스페이스 선언 확인
- 기본적으로 네임스페이스는 클래스 등을 중괄호로 묶어 관리합니다.
변환 도구 사용
- Visual Studio에서 네임스페이스 영역을 선택한 후 Ctrl + . 단축키를 누릅니다.
- 나타나는 드라이버(노란 전구) 아이콘을 클릭하면
파일 범위 네임스페이스로 변환
옵션이 표시됩니다.
변환 결과 확인
- 변환 후, 네임스페이스는 한 줄로 간단히 선언되고, 중괄호는 제거됩니다.
마무리
파일 범위 네임스페이스는 C# 10 이상에서만 사용할 수 있으며, .NET Framework 기반 프로젝트에서는 지원되지 않습니다. 이 기능은 다음과 같은 장점을 제공합니다.
- 줄 수 감소: 중괄호를 없애서 2줄을 줄일 수 있습니다.
- 가독성 향상: 클래스와 같은 작업 영역의 들여쓰기가 한 단계 줄어듭니다.
처음에는 "왜 이런 기능을 추가했지?"라고 생각했지만, 사용하다 보니 코드가 훨씬 깔끔해지고 간결해졌습니다. 지금은 없어서는 안 될 필수 기능으로 자리 잡았습니다.
장 요약
네임스페이스는 프로그램을 하나의 브랜드로 묶어서 관리할 수 있습니다. C#에서 최소한의 단위는 클래스이지만, 클래스들을 네임스페이스로 묶어서 관리할 때 네임스페이스 이름은 일반적으로 회사 이름, 소프트웨어 이름, 브랜드 이름, 도메인 이름 등으로 설정합니다. 이 강의에서는 지면을 아끼기 위해 네임스페이스를 생략하지만, 실제 소프트웨어를 제작할 때는 반드시 의미 있는 이름을 포함해서 만들어 사용한다는 점을 기억하세요. 자, 클래스와 네임스페이스를 다루어 보았으니, 클래스의 주요 구성 요소들을 하나씩 정리해 나가겠습니다.