12.2 Delegate의 구현(Implementation)
메서드를 보다 효율적으로 호출하기 위한 방법으로 Delegate를 구현한다고 했으니 이번 절에서는 Delegate를 실제 적용해서 구현해 보도록 하겠습니다. 앞에서 살펴본 구현의 절차를 여기에서 차례대로 다시 한번 살펴보시기 바랍니다. 이번 절에서 소개되는 Delegate의 구현은 일반적인 메서드와 static 메서드를 사용하여 Delegate로 만든 것입니다. 다음의 예제를 우선 감상하시죠.
& |
DelegateTest.cs |
Ü Delegate를 테스트하는 예제 |
using System; | ||
C:\C#Example\12>csc DelegateTest.cs C:\C#Example\12>DelegateTest Normal Method입니다.!! Jabook Static Method입니다.!! 소설같은 C# |
예제는 Delegate를 생성하여 그 Delegate에 객체의 메서드를 지정합니다. 그리고, Delegate 객체를 호출함으로써 객체의 메서드를 호출하는 것과 같은 효과를 볼 수 있습니다. 다음의 그림은 일반적인 메서드를 호출할 때의 형태를 그림으로 나타낸 것입니다.
그림 12-1 일반 메서드 호출
위와 같은 일반적인 메서드의 호출은 아래의 그림과 같이 Delegate의 호출로 전환할 수 있습니다. 여기서 한가지 주의하실 것은 스태틱과 일반 멤버메서드에 상관없이 메서드의 시그너쳐만 같다면 같은 Delegate로 동작시킬 수 있다는 것입니다. 다만, Delegate를 만들 때 메서드의 반환형과 메서드의 매개변수를 Delegate에 맞추어 주면 됩니다.
그림 12-2 Delegate 호출
예제를 보면 StaticMethod() 메서드나 NormalMethod() 메서드를 호출한 적은 없습니다. 하지만, 결과를 보면 두 메서드가 호출되어 예쁘게 실행되었군요. 이것은 메서드를 직접 호출한 것이 아니라 Delegate를 사용하여 간접적으로 메서드를 호출한 것입니다. 예제를 보면서 자세하게 설명드리도록 하겠습니다.
먼저, Delegate를 선언하였습니다. Delegate는 delegate 키워드를 사용하여 선언합니다. 이 부분은 마치 클래스를 디자인하는 것처럼, 사용하려는 Delegate의 형을 디자인한다고 생각하시면 됩니다.
delegate void TopDelegator(string str);
Delegate를 선언할 때 규칙이 있습니다. 제일 중요하다고 할 수 있는 것은 캡슐화하려는 메서드의 반환형과 Delegate의 반환형이 일치해야 한다는 것입니다. 위의 선언을 보면 반환형이 void로 선언된 메서드를 대신하겠다는 의미입니다. 또한 메서드의 매개변수와 Delegate의 매개변수도 일치시켜야 합니다.
▣ Delegate의 선언 |
ㅁ 사용하려는 Delegate의 형을 생성하는 부분 public delegate void TopDelegator(string str); ㅁ 메서드의 선언(시그너쳐) public void NormalMethod(string str) public static void StaticMethod(string str) |
이제 생성된 Delegate형을 바탕으로 Delegate 객체를 생성해야 합니다. 클래스를 객체로 생성할 때와 마찬가지라고 생각하시면 됩니다. 다만, 한가지 차이점이 있다면 이 때 사용될 메서드명을 매개변수로 넣어 준다는 점입니다. 즉, 괄호( )를 뺀 메서드의 이름을 매개변수로 넣어 주면 Delegate 객체가 생성됩니다.
Top t = new Top();
TopDelegator td1= new TopDelegator(t.NormalMethod);
TopDelegator td2 = new TopDelegator(Top.StaticMethod);
▣ Delegate의 생성 |
ㅁ 생성된 Delegate 타입으로부터 Delegate 객체를 생성하는 부분 Delegate 객체를 만들 때의 매개변수는 메서드의 이름이다. [예] TopDelegator dele=new TopDelegator (t.NormalMethod); |
이제 생성된 Delegate 객체를 호출해 주면 메서드를 호출해 준 것과 같은 결과가 나오게 됩니다. 이 때 매개변수를 Delegate 객체에 직접 집어 넣어서 호출해 주어야 합니다.
td1("Jabook");
td2("소설같은 C#");
▣ Delegate를 사용하여 메서드 호출하기 |
ㅁ 생성된 Delegate 객체를 사용하여 메서드를 호출하는 부분 td1("Jabook") td2("소설같은 C#") |
메서드는 일반 메서드나, 스태틱으로 선언된 메서드 모두 사용할 수 있습니다.
그럼, Delegate를 왜 사용하는 것일까요? Delegate는 메서드를 캡슐화 한다고 하였습니다. 조금 어렵게 생각해 보면, Delegate 객체를 생성하는 것은 메서드의 참조자를 일반화된 형식으로 만든다는 의미입니다. 이런 Delegate의 장점은 프로그램이 컴파일할 때가 아니라 런타임에 참조하는 메서드에 접근하여 메서드를 호출할 수 있다는 것입니다. C나 C++에서 함수 포인터와 같은 역할을 합니다. 함수 포인터를 알고 계신 분은 그 쪽으로 생각해도 좋을 것입니다.
[출처] [펌] Delegate의 구현(Implementation)|작성자 눈꽃천사