이번 주제는 실제 코딩보다는 환경 설정 문제, 아키텍처 설계 문제에 직면할만한 문제 중 하나로 포스팅했다

 

네임스페이스 : 서로 다른 타입들의 특성과 성향을 논리적으로 그룹화하기 위한 수단이다.

어셈블리       : 네임스페이스에 그룹화 되어 있는 타입의 구현체 (ex. exe, dll)로 보면 된다.

 

using System.IO; // IO 기능을 위한 네임스페이스
using System.Text; //Text 기능을 위한 네임스페이스

FileStream fs = new FileStream(...);
StringBuilder sb = new StringBuilder();

c# 개발자들은 위와같은 using 지시자 구문으로 네임스페이스를 지정한다. 만약 네임스페이스 가없다면 아래와 같이 복잡하게 작성해야 한다.

System.IO.FileStream fs = new System.IO.FileStream(...);
System.Text.StringBuilder sb = new System.Text.StringBuilder();

CLR은 C# 코드 중 using 구문은 신경 쓰지 않는다. 왜냐하면 컴파일 단계에서 C# 컴파일러가 작성된 using 구문으로 메서드의 반환 값, 인수의 개수와 타입을 탐색하며 두 번째와 같은 코드로 변경시키기 때문이다.

실제로 컴파일러는 FileStream fs와 같은 문구를 만나면 using 지시자에 정의되어있는  System.IO, System.Text를 탐색해 FileStream 타입이 있는지 찾아낸다. 이런 컴파일러의 동작 덕분에 우리 개발자들은 조금 더 깨끗한 코드를 작성할 수 있다.

 

System.IO.FileStream 타입을 찾아낸 컴파일러는 그다음 무엇을 할까??

 

바로 어셈블리를 탐색 한다. 그리고 특정 타입에 대한 정보와 일치하는 어셈블리를 발견하면 어셈블리 정보와 타입 정보가 만들어지는 관리 모듈의 메타 데이터상에 기록시킨다. 그리고 CLR은 관리 모듈메타 데이터를 읽고 수행하는 것이다.

C# 컴파일러는 기본적으로 MSCORLIB.DLL어셈블리를 따로 지정하지 않더라도 자동으로 찾아볼 대상에 포함시키고 있다.

MSCORLIB.DLL에는 무엇이 있을까??

 

C# MSDN에서 기본 타입에 대해 조금만 찾아봐도 참조한 어셈블리에 포함되어있다.

docs.microsoft.com/ko-kr/dotnet/csharp/

 

C# 문서 - 시작, 자습서, 참조.

프로그래밍 C# 알아보기 - 초보 개발자, C#을 처음 사용하는 개발자, 숙련된 C# / .NET 개발자용

docs.microsoft.com

 

MSCORLIB.DLL은 기본적으로 Object, Int32, double, String 등 핵심적인 타입들은 모두 포함하는 FCL이 들어있다.

 

네임스페이스를 씀으로 써 일반적으로 겪을 수 있는 문제

회사 A와 회사 B가 제공하는 DLL을 동시에 쓴다고 할 때 A사의 Widget, B사의 Widget을 쓰는 상황

using A;
using B;

Widget w = new Widget(); //A.Widget? B.Widget?

위의 코드는  컴파일러가 A.Widget, B.Widget의 모호한 참조 오류가 발생한다.

그래서 위의 모호성을 없애기 위해서 1번 해결 방법은 using 지시자 구문을 쓰지 않는 것이다.

A.Widget w = new A.Widget(); //A.Widget

그리고 두 번째 해결 방법

using AWidth = A.Widget;
AWidth w = new AWidth(); //A.Widget

이렇게 우리는 참조의 모호성을 해결했다.

일반적으로 제3자가 사용하는 타입을 설계하는 경우, 반드시 이러한 타입들을 별도의 네임스페이스상에 정의하여 컴파일러가 쉽게 타입을 구분할 수 있도록 설계해야 한다. 위의 예시에서 안 좋게 나왔지만 사실 주요 방법은 앞에 회사명.으로 시작하는 네임스페이스로 지시하는 방법이 일반적이다. 실제 Microsoft도 Microsoft.CSharp, Microsoft.VisualBasic을 쓴다고 한다.

 

추가로 C#코드에서 네임스페이스 선언 방법이다

namepsace Name{
    public Class A{...} //Name.A
    
    namespace Donghee
    {
        public class B{...} //Name.Donghee.B
    }
}

네임스페이스와 어셈블리 사이의 연관성

네임스페이스와 어셈블리에 대해서는 필요 불충분의 관계이고, 이는 연관성이 별로 없다는 뜻이다. 무슨 말이냐 하면 System.IO.FileStream 클래스 타입은 mscrolib.dll에 System.IO.FileSystemWatcher 클래스 타입은 System.dll에 들어 있다. 즉 앞에 System.IO가 동일하다고 해서 동일한 어셈블리에 포함되어 있는 것이 아니다. 추가로 하나의 어셈블리에 2개 이상의 네임스페이스가 포함될 수도 있다. (ex. System.Int32, System.Text.StringBuilder는 mscrolib.dll에 같이 정의되어있음)

정리하자면

 

- 네임스페이스가 같다고 하나의 어셈블리에 포함되어 있지 않다.

- 하나의 어셈블리에 2개 이상의 네임스페이스가 포함될 수 있다.

 

예시 Class ResXFileRef 

네임스페이스 :  System.Resources

어셈블리      :  System.Windows.Forms.dll

 

docs.microsoft.com/ko-kr/dotnet/api/system.resources.resxfileref.-ctor?view=net-5.0

 

ResXFileRef 생성자 (System.Resources)

ResXFileRef 클래스의 새 인스턴스를 초기화합니다.Initializes a new instance of the ResXFileRef class.

docs.microsoft.com

 

'Program > C#' 카테고리의 다른 글

const 상수  (1) 2020.12.20
값타입의 박싱과 언박싱  (1) 2020.12.14
값 타입, 참조 타입  (0) 2020.12.13
타입에 대하여2  (0) 2020.12.02
타입에 대하여1  (1) 2020.11.29

+ Recent posts