요약:

delegate는 함수 포인터의 역할을 하기 때문에 클래스내 public 필드에 있을 시, 외부에서 호출도 가능하고 delegate가 가르키는 함수를 변경할 수도 있다. 하지만 event키워드가 붙어있다면 해당 딜리게이트는 외부에서 변경은 할수 있지만 호출은 그 딜리게이트를 멤버변수로 가진 클래스 내부에서만 호출이 가능하다.

델리게이트 (Delegate)

델리게이트는 메서드에 대한 참조 (C++로 치면 함수포인터), 즉 델리게이트는 하나의 형식이다.

델리게이트는 인스턴스 메서드, 정적 메서드 모두 참조가 가능하다.

델리게이트는 값이 아닌 코드(메서드) 자체를 넘기고 싶을때 사용할 수 있다.

이벤트 (Event)

이벤트는 델리게이트를 event 한정자로 수식해서 만든다.

  1. 델리게이트를 선언합니다. (이 델리게이트는 클래스 안과 밖 아무곳에나 선언해도 됩니다.)
  2. 클래스내에 1번에서 선언한 델리게이트의 인스턴스를 event 한정자로 수식하여 선언합니다.
  3. 이벤트 핸들러를 작성합니다. 이벤트 핸들러는 1번에서 선언한 델리게이트와 일치하는 메소드여야 합니다.
  4. 클래스의 인스턴스를 생성하고 이 객체의 이벤트에 3번에서 작성한 이벤트 핸들러를 등록합니다.
  5. 이벤트가 발생하면 이벤트 핸들러가 호출됩니다.

이벤트는 대리자에 event 키워드로 수식해서 선언한 것에 불과한데, C#은 왜 event를 지원할까?

'외부에서 직접 사용할 수 없다'라는 이벤트의 성격 때문이다! 이벤트는 public 한정자로 선언되어 있어도 자신이 선언된 클래스 외부에서는 호출이 불가능하다. 반면 대리자는 public이나 internal로 수식되어 있으면 클래스 외부에서라도 얼마든지 호출이 가능하다.

즉, Event를 사용하면 견고한 이벤트 기반 프로그래밍을 할 수 있는 반면에 대리자는 위협을 막을 수 없다. 따라서 대리자는 '콜백' 용도로 사용하고, 이벤트는 '객체의 상태 변화나 사건의 발생을 알리는 용도'로 구분해서 사용해야 한다.