본문 바로가기

프로그램&DB/C#

[C# 강좌] C# 프로그래밍 #03 - namespace와 using

2. 기본 구문

2.1 namespace using

2.1.1 namespace

Java를 해보았다면 패키지(package)라는 개념에 익숙해져 있을 것이다. C#의 네임스페이스(namespace)는 이와 유사하다고 보면 쉽게 이해할 수 있을 것이다. 네임스페이스(namespace)를 이용하는 주된 목적은 네임스페이스를 이용하여 클래스를 묶어 손쉽게 관리하기 위한 목적과 네임스페이스 범위로 코드를 구성하여 사용자가 클래스 및 메서드 이름의 범위를 쉽게 제어하는데 있다.

실제 C#에서 많은 클래스들은 그들의 성격에 따라 네임스페이스(namespace)로 묶어서 관리된다. C#.NET 의 시스템 네임스페이스는 System으로 시작하며 수많은 클래스들을 포함하고 있다. 대표적인 예로 앞서 예제에서 이용된 Console클래스를 비롯하여 Int, Boolean, String과 같은 형식 선언들이 모두 System 네임스페이스로 묶여 있다.

네임스페이스는 .으로 구분되어 관리 될 수 있다.

네임스페이스의 선언은 namespace 키워드를 이용하여 선언한다.

namespace MyNamespace1.MyNamespace2

{

    class Program

    {

static void Main(string[] args)

        {

        }

    }

}

 

이 예제는 .을 기준으로 네임스페이스를 2단계로 구성하였다. 이는 아래 소스와 동일하다.

namespace MyNamespace1

{

namespace MyNamespace2

{

        class Program

        {

static void Main(string[] args)

            {

            }

        }

    }

}

 

네임스페이스는 DLL과 같은 라이브러리를 제작하여 이용할 때, 사용자 라이브러리의 기능을 명시적으로 표현해줄 수 있는 이름으로 이용되곤 한다.

* 네임스페이스를 지정하지 않고 소스코드를 작성하면 기본 네임스페이스가 자동으로 만들어진다.

* :: 연산자는 네임스페이스 별칭 한정자 연산자로 식별자 조회를 위해 이용된다.

 

2.1.2 using

C#으로 프로그램을 작성할 때 매번 빠지지 않고 나오는 키워드가 using이라는 키워드이다. using의 용도는 다음과 같다.

1) 개체 이용의 편의성

C#으로 구현된 코드들은 최상위에 using 키워드를 통해 네임스페이스를 지정하고 있는 것을 볼 수 있을 것이다. 이와 같이 이용하는 이유는 개발할 때 한정된 네임스페이스를 이용하면 네임스페이스에 대한 전체 이름을 참조하지 않고도, 선언된 네임스페이스 내부에 있는 개체들에 접근하는 것이 가능하기 때문이다. 이는 불필요한 코드 타이핑을 줄일 수 있다. 또한, 지시자를 통해 선언하고 시작함으로써 코드가 명시적으로 어떠한 네임스페이스들을 참조하여 만들어져 있는지 확인하기 쉬워진다. 실제 지시자 using을 사용하는데 있어, 주의하여야 할 것은 using C C++ include 구문처럼 헤더파일이나 라이브러리 파일을 가르는 것이 아니라 네임스페이스(namespace)이름을 나타낸다는 것이다.

앞서 사용된 예제를 다시 보면,

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

using System;

using System.Collections.Generic;

using System.Text;

 

namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.WriteLine("Hello, C#.");

Console.Read();

        }

    }

}

 

1번째 라인에 using System; 구문을 통해 선언해 놓았기 때문에 11번째 라인은 System.Console.WriteLine("Hello, C#."); 대신에 Console.WriteLine("Hello, C#."); 처럼 사용할 수 있게 된다. 12번째 라인 역시 System 네임스페이스에 속한 Console클래스의 Read 메서드를 Console.Read();와 같이 사용할 수 있게 된다.

 

이외에 using은 네임스페이스의 별칭을 지정하는데 이용될 수도 있다. 다시 이전의 소스를 수정해 보자. 앞의 소스와 1번째 라인과 11, 12번째 라인을 비교해보자.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

using MyClass = System.Console;

using System.Collections.Generic;

using System.Text;

 

namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

MyClass.WriteLine("Hello, C#");

            MyClass.Read();

        }

    }

}

 

의 소스와 비교해보면 1번째 라인은 using System;  using MyClass = System.Console; 로 바뀌었다는 것을 알 수 있다. 현 소스의 1번째 라인의 의미는 System 네임스페이스의 Console 클래스에 대한 별칭을 MyClass로 주겠다는 것을 의미한다. 이렇게 이용함으로써 긴 이름이나 복잡한 이름에 대한 별칭을 쉽게 지정할 수 있고 11, 12번째 라인에서 이용한 것처럼 별칭을 이용해 메서드를 호출할 수 있게 된다.

별칭에 대한 대상은 네임스페이스나 형식 클래스가 될 수 있으며, 적절한 별칭의 사용은 코드를 읽기 쉽게 만드는데 기여할 수 있다.

 

2) 범위 한정

using의 중요한 기능 중 하나는 범위 제한에 있다. .NET Garbage Collector에 의해 제어되는데, Garbage Collector가 수행되는 시기가 객체의 사용이 끝나는 시점과 맞물리지 않는다. 이와 같은 문제는 제한된 리소스를 이용하는 경우 문제점가 발생할 수 있다. 데이터베이스 서버에 연결되어 작업되는 시스템이 있을 때, 데이터베이스 서버는 클라이언트 연결 수에 대한 제한을 가진다. 이 경우 빠른 연결해제가 이루어지지 않으면, 다른 클라이언트에서 연결 초과로 인해 데이터베이스 서버 연결에 실패하는 경우가 발생할 수 있다. 이와 같은 경우 객체의 사용과 해제를 명시적으로 하기 위해 Garbage Collector을 강제로 수행하거나 객체의 범위를 한정시켜 해당 리소스를 해제할 시기를 지정하는 방법을 이용하여야 한다. using은 이 경우 명시적인 리소스 해제 시기를 한정해줄 수 있게 된다. 아래 예제를 보자.

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

using System;

using System.Collections.Generic;

using System.Text;

 

namespace Second

{

    class Program

    {

        static void Main(string[] args)

        {

            using (SomeClass _some1 = new SomeClass())

            {

            }

            Console.WriteLine("Some1 Dispose");

           

            SomeClass _some2 = new SomeClass();

            using (_some2)

            {

            }

            Console.WriteLine("Some2 Dispose");

           

            Console.Read();

        }

    }

 

    class SomeClass : System.IDisposable

    {

        public void Dispose()

        {

            Console.WriteLine("test");

        }

    }

}

 

11~13번째 라인은 using을 통해 SomeClass 개체를 이용하고 있다. 이 경우 using으로 묶여있는 SomeClass는 중괄호로 묶여있는 범위 안에서만 이용되며, 이 범위를 벗어나는 순간 Dispose 메서드가 자동으로 호출되게 된다. 16~19번째 라인은 동일한 역할을 하는 코드를 다른 방법으로 표현한 예이다.

 

* 이 경우 using문에 사용되는 개체는 Dispose 메서드 호출을 통해 개체의 리소스를 해제할 수있도록 하기 위해, IDisposable 인터페이스가 구현되어야 한다.



/* 출처 */
inobae의 놀이터
http://blog.naver.com/inobae