Post List

2018/01/04

C# __6.0 델리게이트(Delegate)_이벤트(Event)

델리게이트
 - 메서드를 가리킬 수 있는 타입으로 delegate라는 예약어를 사용합니다.

[ 접근제한자 ] [ delegate ] [ 대상_메서드의_반환타입 ] [ 식별자(대상_메서드의_매개변수_목록) ];
   public         delegate               int                          FuncDelegate(object arg);
 - 대상이 될 메서드의 반환 타입 및 매개변수 목록과 일치하는 델리게이트 타입을 정의합니다. 

 * C/C++에서는 델리게이트를 함수 포인터라고도 합니다.

ex.1 )
1
int Clean (object arg);
cs
 - 대상 메서드의 반환값과 인자를 분리하고, 식별자만 바꿔줍니다.

1
int FuncDelegate (object arg);
cs
 - 그 상태에서 delegate 예약어를 추가합니다.

1
delegate int FuncDelegate(object arg);
cs
- 델리게이트를 이용해 단 한번의 함수 호출로 연결된 메서드를 모두 호출할 수 있습니다.

ex.2 )
1
2
3
CalcDelegate calc = Add;
calc += Subtract;
calc += Multiply;
cs
calc(10,5); -> add, subtract, multiply 메서드가 동시에 호출됩니다. 여기서 +=는 delegate.combine과 같은 구문이랍니다.
del1 = delegate.combine(del1, del2);
   -> 두개 이상의 델리게이트의 호출 목록을 연결해 주는 역할을 합니다.
       반대로 -=도 가능하며, 연결된 메서드들 중에서 해당 메서드를 제거하는 연산자입니다.

* 콜백 메서드
여기서 Source라는 클래스에서 Target의 메소드를 호출하게되면 Source를 호출자, Target을 피호출자가 됩니다. 이때 피호출자에서 호출자의 메서드를 호출하는 것을 콜백이라합니다. 
콜백은 메서드를 호출하는 것이기 때문에 이 상황에서 실제 필요한 것은 타입이 아니라 하나의 메서드일 뿐입니다. 따라서 메서드에 대한 델리게이트만 전달해서 실수 유발을 방지한다.


델리게이트와 이벤트
 - 이벤트가 델리게이트와 가장 크게 다른점은 이벤트는 외부에서 직접 사용할 수 없다는데 있습니다.
이벤트는 public한정자로 선언되어 있어도 자신이 선언되어 있는 클래스 외부에서는 호출이 불가능합니다. 
반면 델리게이트는 public이나 internal로 수식되어 있으면 클래스 외부에서라도 얼마든지 호출이 가능합니다.

* 이벤트는 이벤트 처리기를 등록하지 않아도 컴파일 에러가 발생하지 않습니다.
덕분에 프로그래머들은 초기화하지 않은 이벤트를 쉽게 놓치곤 하는데, 이런 문제 때문에 이벤트를 선언하면 항상 비어있는 익명메소드로 미리 초기화를 해두기도합니다. 최악의 경우에는 프로그램이 다운되는 것을 막을 수 있으니까요.