C# 개발에서 델리게이트(Delegate)와 이벤트(Event)는 자주 함께 언급되지만, 두 개념은 서로 다른 목적과 특성을 가지고 있습니다. 이 글에서는 두 기능의 차이점을 항목별로 명확하게 정리해 보겠습니다.
델리게이트(Delegate)란?
델리게이트는 메서드를 참조하는 타입으로, C++의 함수 포인터와 유사한 역할을 하지만 훨씬 더 안전하고 객체 지향적입니다.
delegate키워드를 사용하여 선언합니다.본질적으로 함수 포인터 역할을 하며, 런타임에 하나 이상의 메서드에 대한 참조를 보유할 수 있습니다.
독립적인 키워드로, 이벤트에 의존하지 않고 단독으로 사용할 수 있습니다.
Combine()및Remove()메서드를 제공하여 호출 목록(invocation list)에 메서드를 추가하거나 제거할 수 있습니다.메서드의 매개변수로 전달할 수 있어 콜백(callback) 구현에 널리 활용됩니다.
=연산자를 사용하면 단일 메서드를 할당할 수 있습니다.+=연산자를 사용하면 여러 메서드를 델리게이트에 할당(멀티캐스트)할 수 있습니다.
델리게이트 예제
public delegate void Notify(string message);
Notify handler = DisplayMessage; // = 로 단일 메서드 할당
handler += LogMessage; // += 로 메서드 추가
이벤트(Event)란?
이벤트는 델리게이트를 기반으로 하는 알림(notify) 메커니즘입니다. 즉, 델리게이트 위에 캡슐화 계층을 추가한 형태라고 볼 수 있습니다.
event키워드를 사용하여 선언합니다.델리게이트에 의존하며, 델리게이트 없이는 정의할 수 없습니다.
델리게이트 인스턴스를 감싸는 래퍼(wrapper)로 이해할 수 있습니다.
외부에서 델리게이트와 호출 목록 전체를 초기화(
=할당)하는 것을 차단하여 안전성을 높여줍니다.호출 목록에서 핸들러를 추가(
+=)하거나 제거(-=)하는 작업만 허용합니다.이벤트는 발생(raise)시킬 수는 있지만, 메서드의 매개변수로 전달할 수는 없습니다.
EventInfo클래스를 통해 이벤트를 검사(reflection)하고 이벤트 핸들러를 동적으로 바인딩할 수 있습니다. 이 클래스는 호출 목록에 메서드를 추가·제거하는AddEventHandler()및RemoveEventHandler()메서드를 제공합니다.+=와-=연산자는 내부적으로AddEventHandler,RemoveEventHandler와 유사한 접근자(accessor) 메서드를 호출합니다.
이벤트 예제
public class Publisher
{
public event Notify OnMessageReceived; // event 키워드로 선언
public void Send(string msg)
{
OnMessageReceived?.Invoke(msg); // 이벤트 발생
}
}
핵심 차이점 요약
| 구분 | 델리게이트(Delegate) | 이벤트(Event) |
|---|---|---|
| 선언 키워드 | delegate | event |
| 의존성 | 독립적으로 존재 가능 | 반드시 델리게이트 필요 |
| 매개변수 전달 | 가능 | 불가능 (발생만 가능) |
= 연산자 | 사용 가능 | 사용 불가능 |
+= / -= | 메서드 추가/제거 가능 | 핸들러 추가/제거만 가능 |
| 주요 용도 | 콜백, 메서드 참조 | 발행-구독(Pub-Sub) 알림 |
정리하면, 델리게이트는 메서드를 참조하는 타입이고 이벤트는 델리게이트를 안전하게 캡슐화한 알림 메커니즘입니다. 외부 코드가 임의로 호출 목록을 덮어쓰지 못하도록 보호해야 한다면 이벤트를, 단순한 콜백이나 유연한 메서드 참조가 필요하다면 델리게이트를 사용하는 것이 좋습니다.