delegate

C#, .NET 2011. 6. 17. 19:21
delegate 는 한마디로 C의 function pointer 라고 할 수 있다. (함수를 직접 call 하지 않고 대신 call할 수 있어서 이름이 대리자 인듯 하다)

delegate 로 method 의 signature(return type, parameter type)을 명시하며,

method 그 자체를 가리킬 수 있다.

(아무래도 이건 캡슐화를 깨는 feature 인 듯 하다.)

그리고 delegate 도 하나의 type 이므로, new 키워드를 이용하여 메소드와 연결해주면 된다.

delegate type의 선언은 보통 class 외부에서 한다.

이때 delegate type의 선언 앞에 붙은 접근 지정자는 같은 namespace 안에서만 참조할것인지 아닌지 등을 의미하게 된다.


//리턴 타입이 string 이고 인자는 아무것도 받지 않는 메소드를 가리키는 delegate type 선언
public delegate string ReturnsAString(); 
ReturnsAString someMethod;

private string HiThere() {
    return "Hi There!";
}

someMethond = new ReturnsAString(HiThere);
string msg = someMethod();
MessageBox.Show(msg);




<anonymous delegate (무명 대리자)>
delegate 에 이름이 없다니 이게 무슨 소리야.. 내가 내가.. 무명이라니..

ex)
1.이벤트 헨들러 메쏘드를 이벤트에 연결해야 겠는데, 굳이 함수를 또 따로 만들기도 귀찮고.. 임시 함수같은거 못만드나요?
2.메쏘드를 따로 만들어서 메쏘드에 변수를 인자로 일일히 넘기기가 좀 거시기한 상황인가요?

이럴때 무명 대리자를 쓸 수 있다.

1의 경우는 Python 의 lambda function 같은 녀석이겠고
2의 경우는 뭘까... 대응되는게 잘 안 떠오른다. 스코프를 초월[?] 하게 해준다고 할 수 있다.


1. lambda function 스럽게 사용하기

// Create a handler for a click event
button1.Click += delegate(System.Object o, System.EventArgs e)
                   { System.Windows.Forms.MessageBox.Show("Click!"); };

또는

// Create a delegate instance
delegate void Del(int x);

// Instantiate the delegate using an anonymous method
Del d = delegate(int k) { /* ... */ };

이렇게 쓸 때 delegate 함수의
함수이름은 당연히 신경쓸 필요가 없고, 
리턴타입은 delegate type Del 의 리턴타입인 void 가 된다. 
된다.

무명 대리자는 method 를 쓸 자리에 대신 들어가는 것이므로
원래 썼어야할 method 의 signature를 그대로 따른다.

2.scope 초월하기
int n = 0;
Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n); };

여기서 n은 외부변수인데, delegate 가 만들어질 때 캡쳐된다고 한다.

이 용법은 List<> 의 Exist 함수에서 Predicate<> 를 사용해야 하는데
넘길 수 있는 인자는 한정되어 있고 인자는 넘겨야 되겠고 할 때 쓸 수 있을듯.




출처 : http://msdn.microsoft.com/ko-kr/library/0yw3tz5k(VS.80).aspx
Posted by 휘사마
,