Creative Commons License

Microsoft .NET

닷넷!시작하기
닷넷! Ver 2.0~
닷넷!스킬업
웹개발
윈폼개발
실용모듈개발
Tip & Tech
하루 한 문법

Microsoft .NET 개발자들을 위한 공간입니다. 기초강의에서 부터 고급 기술 정보 및 팁등을 다루도록 하겠습니다.

.

닷넷!시작하기

Microsoft. NET 을 시작하는 분들을 위한 강좌입니다. 주로 기초적인 내용과 때론 기본적인 내용을 다룹니다

[C# 기초강좌] 15. C# 네임스페이스(namespace

작성자 : 박종명
최초 작성일 : 2010-07-02 (금요일)
최종 수정일 : 2010-07-02 (금요일)
조회 수 : 6176

네임스페이스는 타입명 충돌을 방지하고 프로그램을 논리적으로 그룹화 시킵니다

 

안녕하세요. 박종명입니다. 닷넷 열다섯 번째 강좌를 진행하도록 하겠습니다

이번 강좌는 닷넷의 네임스페이스(Namespace)에 대해 살펴 보겠습니다

 

네임스페이스의 한글 번역은 이름 공간입니다. 좀 어색하지요? ㅎㅎ

네임스페이스는 프로그램의 요소들을 논리적으로 그룹화 시키는 역할을 하는데요.

그룹화의 목적은 의미 있는 이름으로의 구분은 프로그램을 보다 명료히 하고 다른 요소들과
이름 충돌을 방지하기 위함입니다.

 

 

우린 뭔가 그룹화 시키는 것에 익숙합니다

학창 시절 1, 2,3,.. 이런 식으로 학생들을 그룹화 시켰더랬죠

요즘 유치원에서는 샛별반’, ‘천사반’,.. 뭐 이런 식으로 그룹화 하더군요. 그리고 당장 여러분의 폴더 구조를 보십시오.

여러분의 폴더 구조는 여러분만의 의미 있는 이름으로 계층적 구조를 지니고 있을 거라 봅니다.

 

이렇듯 어떠한 요소(그게 학생이든, 파일이든)들을 의미 있는 이름으로 그룹화 시키면 많은 장점이 있습니다.

만일 한 학년에 홍길동이라는 학생이 두 명 이상 있을 경우 1반 홍길동, 2반 홍길동이라는 구분을 명확히 할 수 있겠죠. (같은 반이면 큰 홍길동’ ‘작은 홍길동인가요? ㅎㅎ)

결과적으로 홍길동이라는 이름에 대한 일종의 중복, 충돌을 방지할 수 있습니다.

 

또한 이러한 충돌 이외에도 의미 있는 이름의 구분은 관리측면에서도 유용한 경우가 많죠.

샛별반에는 샛별 같은 아이들이 있겠구나.. 하고 그룹의 이름으로 구성원의 특성을 연상할 수 있을 겁니다 ^^

 

이렇듯 단위 요소들을 마구잡이로 널어 뜨려 놓는 것보다 특정 기준에 의해 그룹화, 범주화 하는 것은 일상생활에서도

유용하며 프로그램 세계에서도 유사한 형태로 유용하게 사용됩니다

 

 

네임스페이스(namespace)

 

닷넷 프로그램의 결과물에는 많은 구성 요소들이 결합되어 있습니다.

하나의 프로그램에는 하나 이상의 인터페이스, 클래스, 구조체, 이벤트 등의 요소가 포함됩니다.

이러한 요소들을 논리적으로 그룹화 시키는 역할이 네임스페이스를 통해 이루어지게 됩니다.

지금부터 네임스페이스를 사용하는 이유와 문법적 규칙에 대해 알아 봅니다

 

 

의미 있는 논리적 그룹

닷넷이 제공하는 수 많은 라이브러리는 모두 네임스페이스 단위로 나뉘어져 있습니다

FileInfo 클래스, DirectoryInfo 클래스 및 Path 클래스 등은 폴더 및 파일에 대한 조작을 제공하는 API입니다.

이들 파일관련 API들은 System.IO 라는 네임스페이스로 그룹화 지어져 있습니다

그리고 웹 관련 API들은 System.Web이라는 네임스페이스로 묶어져 있습니다.

이처럼 클래스들을 그 역할과 성격에 따라 의미 있게 그룹화 시켜 두면 프로그램의 논리적 기준이 명료해 지며

이 프로그램을 이용하는 외부 개발자도 보다 직관적으로 참조할 수 있게 됩니다

 

 

using 을 통한 참조

네임스페이스를 이용하여 클래스들을 조직화/그룹화 하면 이 클래스를 사용하는 입장에서는

매번 전체 타입의 전체이름을 지정할 필요 없이 using 키워드로 네임스페이스를 참조할 수 있습니다

 

using System.IO; 

FileInfo fi = new FileInfo("test.txt");

DirectoryInfo di = new DirectoryInfo(@"D:\");

 

 

이름 충돌 방지

여러 사람이 공동 작업을 하는 경우 클래스의 이름이 중복될 소지가 많습니다.

특히 대규모 프로젝트일 경우 그 가능성은 더욱 커지죠.

또한 이미 개발된 외부 어셈블리를 이용하는 경우에도 동일한 이름의 타입이 이미 존재할 수 있습니다

 

아래와 같이, 하나의 네임스페이스 안에서는 타입명이 중복될 수 없습니다

 

class MyClass { }

 

class MyClass { } //<-- 컴파일 오류 발생

그러나 서로 다른 네임스페이스로 두 영역을 구분하면 가능합니다

namespace MyNameSpace1{

    class MyClass { }

}

 

namespace MyNameSpace2{

    class MyClass { }

}


결국 네임스페이스를 포함한 이름이 그 타입의 전체 이름이 되며 이 타입이 중복되지 않으면 가능한 것입니다

 

앞서 언급된 닷넷 프레임워크에 이미 정의된 FileInfo 클래스도 개발자가 같은 이름의 다른 클래스로 작성할 수 있습니다. 물론 네임스페이스는 달라야겠죠

namespace MyNameSpace1{

     class FileInfo { }

}

 

두 클래스는 이름은 같지만 네임스페이스가 다르기에 다음과 같이 참조하게 됩니다

static void Main(string[] args){         

    System.IO.FileInfo file1 = new System.IO.FileInfo("test.txt");

    MyNameSpace1.FileInfo file2 = new MyNameSpace1.FileInfo();                       

}

 

 

모호한 참조

네임스페이스로 그룹화 된 이름은 using 키워드로 참조할 수 있다고 하였습니다

 

그렇다면 이런 경우를 생각해 보죠

두 개의 외부 어셈블리를 참조하게 된 경우, 두 어셈블리에 같은 이름의 클래스가 있는 경우 입니다

ConsoleApplication1 네임스페이스에 정의된 MyClass

ConsoleApplication2 네임스페이스에 정의된 MyClass

 

그리고 이를 사용하는 Main 프로그램에서 using 키워드로 두 네임스페이스를 참조하도록 합니다

그리고 다음과 같이 메인에서 MyClass를 사용하려 합니다

 

using ConsoleApplication2;

using ConsoleApplication3;

 

class Program{

    static void Main(string[] args) {

 MyClass m = new MyClass();//모호한 참조

    }

}

 

MyClass 는 두 네임스페이스에 모두 정의되어 있습니다. 따라서 어떤 것을 가리키는지 불분명 한 것이죠

위 코드는 다음과 같은 컴파일 오류를 발생합니다

비록 using 키워드로 특정 네임스페이스를 지정했더라도 이렇듯 모호한 참조가 있을 경우에는 전체 이름을 지정해 줘야 합니다

 

static void Main(string[] args){

    ConsoleApplication2.MyClass m = new ConsoleApplication2.MyClass();

}

 

 

네임스페이스에 별칭 주기

using 키워드를 이용하면 네임스페이스에 별칭을 부여할 수 있습니다

네임스페이스 별칭은 외부 어셈블리를 사용하는 입장에서 유용한 도구입니다

 

만일 가져다 쓰는 외부 어셈블리에 다음과 같은 네임스페이스가 있다고 가정합니다

namespace MyCompany.MyDept.MyPosition.MyName

 

의미부여를 너무 했나요? ^^ 이름이 굉장히 깁니다

 

대부분의 경우 using 키워드로 네임스페이스를 한번만 참조해 주면 프로그램에서 더 이상 네임스페이스를 작성하지 않아도 되지만 앞서 모호한 참조의 경우나 특별히 프로그램에서 네임스페이스를 직접 지정하고 싶을 경우 복잡한 이름은 걸림돌이 되죠.

 

이럴 경우 짧고 보다 의미 있는 나만의 별칭을 이용할 수 있습니다

 

using That = MyCompany.MyDept.MyPosition.MyName;

 

이렇게 긴 이름에 That라는 짤막한 별칭을 부여하여 프로그램에서 이를 보다 직관적으로 이용할 수 있게 됩니다.

 

 

 

전역 네임스페이스 한정자 (global 키워드)

네임스페이스 참조 시 global 키워드를 이용하면 전역 네임스페이스를 참조할 수 있습니다

이는 개발자에 의해 정의된 개체 이름에 의해 다른 개체의 이름이 가려 졌을 경우 이용되는데요

 

다음의 코드를 보겠습니다

 

class Program {

    class System { }

 

    const int Console = 7;

 

    static void Main(string[] args){

        Console.WriteLine("hi"); //컴파일 오류. 여기에서 Console는 앞서 정의한 상수가 됩니다

    }

}

 

닷넷 프레임워크에 System 이라는 네임스페이스가 있으며 Console 이라는 클래스도 이미 있습니다

그런데 이 두 이름이 이 프로그램에서는 다른 의미로 새롭게 정의되었습니다

 

그러나 여전히 닷넷 프레임워크에서 제공하는 Console.WriteLine 를 이용하고 싶군요.

그러나 코드는 컴파일 오류가 발생합니다. Console 이라는 개체는 앞서 const로 정의된 상수이지

닷넷 프레임워크의 System.Console 클래스가 아닙니다

 

그러면 다음과 같이 전체 이름을 주면?

static void Main(string[] args){

    System.Console.WriteLine("hi"); //컴파일 오류. 여기에서 System은 앞서 정의한 클래스가 됩니다

}

 

역시 컴파일 오류가 납니다. System 역시 앞서 사용자가 따로 정의한 System 클래스가 되기 때문입니다

 

닷넷의 System 네임스페이스와 Console 클래스가 사용자 정의 개체로 인해 가려지게 된 것입니다

이와 같은 상황에서 전역 네임스페이스를 참조하면 문제가 해결됩니다

 

static void Main(string[] args){

    global::System.Console.WriteLine("hi"); //성공

}

 

global 키워드를 이용하면 오른쪽 개체 이름은 전역 네임스페이스에서 시작되어 원하는 객체를 찾을 수 있게 됩니다

 

 

외부 별칭 (extern alias 참조)

네임스페이스에 별칭을 주는 방법 중 외부 별칭이란 것이 있습니다

외부 별칭은 두 어셈블리가 동일한 네임스페이스로 구성되어 있을 경우 이 둘을 구분하기 위해 사용됩니다

이런 경우를 생각해 보죠

 

A사의 어셈블리 정보(ClassLibrary1.dll) >

 ClassLibrary1 네임스페이스에 Class1 클래스, ClassLibrary1. Class1 클래스 존재

 

B사의 어셈블리 정보(ClassLibrary2.dll) >

 ClassLibrary1 네임스페이스에 Class1 클래스, ClassLibrary1. Class1 클래스 존재

 

A,B 사가 제공하는 두 어셈블리의 네임스페이스와 클래스 명이 완전 동일합니다

이 두 어셈블리를 참조하여 사용할 경우 다음의 코드는 컴파일 오류를 일으킵니다

 

static void Main(string[] args){

    ClassLibrary1.Class1 c1 = new ClassLibrary1.Class1();

}

오류 정보를 보면 ClassLibrary1.Class1 라는 형식이 두 어셈블리(ClassLibrary1.dll, ClassLibrary2.dll)

모두 정의되어 있다는 내용입니다

 

앞서 global 키워드로 해결 가능할까요?

직접 해 보면 global 키워드로도 해결할 수 없는 것을 알 수 있습니다

 

이때 필요한 것이 외부 별칭입니다

두 어셈블리는 실제로 다른 파일입니다. 따라서 이 어셈블리를 참조할 때 따로 별칭을 부여하면 되는 것입니다.

 

명령줄 컴파일의 경우 /reference:별칭= ClassLibrary1.dll 형태로 옵션을 주면 되고,

VS환경에서는 다음 그림과 같이 참조한 어셈블리에 별칭을 따로 부여하면 됩니다

 

예를 들어 ClassLibrary1.dll 의 별칭은 C1으로 ClassLibrary2.dll의 별칭은 C2로 부여하는 것입니다

아래 그림은 C1별칭을 부여하는 모습입니다

이렇게 물리적인 어셈블리에 별칭을 부여하고 난 뒤 exteran alias 키워드로 참조하면 됩니다

using 참조가 아님에 유의하십시오

 

다음 코드는 이 두 어셈블리를 외부 별칭을 이용해 사용하는 예제 입니다

참고로 extern 별칭 선언은 다른 모든 네임스페이스 참조(using 참조)보다 앞에 와야 합니다

 

extern alias C1;

extern alias C2;

 

using System;

using System.Collections.Generic;

using System.Text;

 

class Program

{

    static void Main(string[] args)

    {

        C1::ClassLibrary1.Class1 c1 = new C1::ClassLibrary1.Class1();

        C2::ClassLibrary1.Class1 c2 = new C2::ClassLibrary1.Class1();      

    }

}

 

 

네임스페이스 중첩

네임스페이스는 중첩하여 정의할 수 있습니다. 아래 코드는 3번 중첩된 네임스페이스 입니다

 

namespace MyNameSpace.ONE

{

namespace MyNameSpace.TWO

{

     namespace MyNameSpace.THREE

     {

        class MyClass { }

     }

}

}

물론 위와 같은 코드를 작성할 이유는 없겠죠?

다만 논리적 그룹에 계층적 효과까지 더하고 싶을 경우 네임스페이스를 중첩해 사용하기도 합니다

 

 

 

자바의 패키지와 닷넷의 네임스페이스

 

마지막으로 자바와 비교를 좀 해 보겠습니다

닷넷의 네임스페이스는 자바의 패키지와 개념적으로 매우 유사합니다

그리고 자바의 import 역시 닷넷의 using 과 유사하구요

 

프로그램의 이름 충돌을 방지하고 의미 있게 범주화(그룹화) 하여 관리 편의성을 기대한다는 측면에서 그 역할과 필요성이 거의 동일하다고 판단됩니다

 

그러나 언어 규칙적인 측면 즉 일종의 문법적 규칙에는 약간의 차이가 있습니다

 

닷넷의 네임스페이스는 물리적 디렉터리 및 파일 구조와 연관이 없습니다

자바의 경우 패키지에 명명한 이름 및 계층 구조가 물리적인 시스템 디렉터리(폴더) 구조와 동일해야 하지만

닷넷의 경우 네임스페이스의 이름과 계층 구조는 시스템 디렉터리 및 파일과 아무런 연관성이 없습니다

 

닷넷의 메인클래스 역시 파일이름과 달라도 되며 이는 결국 닷넷의 네임스페이스와 클래스 이름은

물리적인 디렉터리, 파일, 어셈블리의 이름과는 별도로 관리할 수 있다는 예기가 됩니다

 

 

닷넷의 네임스페이스는 하나의 파일에 여러 개를 정의할 수 있습니다

자바의 경우 동일한 소스파일에서 패키지를 여러 개 정의할 수 없는 반면, 닷넷에서는 하나의 cs 파일에 여러 개의 네임스페이스를 정의할 수 있습니다

 

 

닷넷의 using 키워드로 직접 클래스를 지정할 수 없습니다

자바의 경우 import 키워드를 통해 특정 클래스 단위까지 지정할 수 있지만 닷넷에서는 using 을 통해 네임스페이스

단위까지만 지정 가능합니다

 

즉 자바에서는 ‘import 패키지이름.클래스이름의 형태가 가능하지만 닷넷에서는 using 네임스페이스이름.클래스이름의 형태를 지원하지 않습니다.

 

다시 말해 using 네임스페이스이름 까지만 지정할 수 있습니다

‘using 네임스페이스이름은 자바의 특정 네임스페이스의 모든 요소를 참조하는 ‘import 패키지이름.*’; 와 동일합니다

 

 

이상 강좌를 마치도록 하겠습니다

즐거운 주말 되세요~~~

이름
비밀번호
홈페이지
YB <- 왼쪽의 문자를 오른쪽 박스에 똑같이 입력해 주세요