2018년 10월 4일 목요일

[C#] Delegate, Func, Action

Delegate

Delegate는 C/C++의 함수 포인터와 유사하다.
* Caller -> Delegate (-> Callee)

이론적(?)으론 원하는 메서드를 안전하게 감싸는(캡슐화) 것이지만
주 활용 목적은 1) 콜백, 2) 메서드-체인 구성(멀티캐스트~이벤트), 3) '동작을 지정하는 틀'을 만드는 것에 있는 것 같다.

예}
string을 인수로 사용하고 void 반환 타입 메서드를 캡슐화 하고자 한다면 동일하게 string을 인수로 사용하고 void 반환 타입을 갖는 delegate를 선언해 주면 된다.

public static void DelegateMethod(string message) { ... }
public delegate string Del(int id);

Generic Delegate로도 선언할 수 있다.
public delegate void Del<T>(T message);

대리자의 형식은 대리자의 이름으로 정의된다.
위 예시에서 Delegate의 이름이 'Del'이므로 형식은 'Del'이 된다.
Del handler = DelegateMethod;
handler("hello world");

익명 메서드나 람다도 물론 허용한다.
{익명 메서드} Del handler = delegate(string message) { Console.WriteLine(message); };
 -> 익명 메서드는 이름이 없는 메서드기 때문에 이를 호출하기 위해서 delegate 키워드가 필요한 것이다.
{람다} Del handler = (string message) => Console.WriteLine(message);

Delegate는 객체이기 때문에 매개 변수로 전달하거나 속성에 할당할 수 있다.
메서드의 매개 변수가 될 수 있는 점은 꽤나 유용하다. (ex. 비동기 콜백)

Delegate의 또 하나의 큰 특징으로 둘 이상의 메서드를 호출할 수 있다.
이러한 호출을 멀티캐스트라고 한다.
Del d1 = Func1;
Del d2 = Func2;
Del d3 = Func3;
Del allMethodsDelegate = d1 + d2;
allMethodDelegate += d3;

allMethodDelegate("hello world"); // Func1 > Func2 > Func3 으로 호출된다.

멀티캐스트 대리자는 이벤트 처리에서 광범위하게 사용된다.


C#에서의 Delegate vs Event

Delegate는 자신이 속한 클래스 외부에서도 호출이 가능하지만,
Event는 자신이 속한 클래스 내부에서만 호출하도록 강제된다.

! 참고로 event는 단지 delegate 앞에 'event' 키워드만 붙이는 것으로 선언이 된다.
Del myDelegate; -> event Del myEvent;


Func, Action

Func와 ActionFunc와 Action은 미리 선언된 Delegate 변수로
Func는 반환값이 있고, Action은 반환값이 없는 차이가 있다.

Func 선언은 매개변수를 앞에 지정하고, 반환 값은 가장 뒤에 지정한다.
Func<int, float> func = (a) => a * 0.1f; // int형 매개변수를 1개 갖고, 반환값은 float 형.

댓글 없음:

댓글 쓰기