C#의 Event를 활용하기 위해서 공부를 하고있는데 책을 보니 너무 내용이 깊게 들어가고 문맥이 이해가 잘 되지 않아서 이 포스팅에서는 최대한 쉽게 정리해봄.
C#에서 이벤트는 특정 액션이나 상황이 발생했을 때 그것을 알리기 위해 사용되는 메커니즘이다.
이벤트는 객체 지향 프로그래밍에서 객체 간의 통신을 위한 중요한 수단이며, 주로 GUI 프로그래밍, 비동기 프로그래밍, 그리고 컴포넌트 기반 설계에서 널리 사용된다.
이벤트를 사용하면, 한 객체가 다른 객체에게 어떤 일이 일어났다는 것을 알릴 수 있으며, 이를 통해 느슨한 결합(loose coupling)과 높은 응집도(high cohesion)를 유지할 수 있다고 한다.
이벤트 선언: 이벤트는 델리게이트(delegate)를 사용하여 선언된다. 델리게이트는 메서드를 참조할 수 있는 타입으로, 이벤트는 이 델리게이트를 기반으로 구독자(subscriber)가 이벤트 발생 시 호출할 메서드 목록을 관리한다.
이벤트 발생(raise): 이벤트를 발생시키는 것은 이벤트를 선언한 클래스 내에서만 가능하다.
이벤트는 일반적으로 메서드 내에서 EventName?.Invoke(this, eventArgs) 형태로 발생시키며, 여기서 EventName은 이벤트의 이름이고 eventArgs는 이벤트와 관련된 추가 데이터를 담고 있는 EventArgs 객체 또는 그 파생 객체다.
이벤트 구독(Subscription): 이벤트에 대한 구독은 += 연산자를 사용하여 이벤트 핸들러를 이벤트에 추가함으로써 이루어진다.
이벤트 핸들러는 이벤트가 발생했을 때 호출되는 메서드.
이벤트 처리(Handling): 이벤트가 발생하면, 그 이벤트에 구독된 모든 이벤트 핸들러가 호출됩니다. 이벤트 핸들러는 일반적으로(C# 관례상) sender 객체와 EventArgs 객체(또는 그 파생 객체)를 매개변수로 받다. sender는 이벤트를 발생시킨 객체를 참조하고, EventArgs 객체는 이벤트와 관련된 데이터를 포함한다.
정적 이벤트라면 sender에 null를 할당한다.
이벤트 전에 델리게이트와 연관지어서 여러 개념들을 보다보니 햇갈리고 뭔 소린지 이해가 잘안되는 부분이 많았어서 더 쉬운 코드로 먼저 예를 든다.
== 이벤트에 대한 간단한 예제 ==
일상생활에서 파티를 예로 듬.
파티 개최자 = 이벤트 개최자(publisher) - 이벤트 게시자
역할 : 게시자의 역할은 파티를 준비하고 관심 있는 사람들에게 이벤트가 발생했음(파티 개최)을 알리는 것
파티 초대장 - 대리자(Delegate)
파티에 사람들을 초대하기 위해 초대장을 보낸다. 이 초대장이 '대리자'의 역할을 한다.
=> 파티에 오라는 메시지를 전달하는 매개체.
프로그래밍에서 대리자는 특정 메서드(파티에 오라는 메시지)를 참조하는 타입.
이 대리자를 통해 어떤 메서드를 호출할지 정의할 수 있다.
=> 이벤트를 선언할 때 만드는 delegate가 이 초대장의 모양? 형태? 같은 것이라고 이해하면 될 것 같다.
초대받은 친구들 - 구독자
초대장을 받은 친구들은 이벤트의 구독자가 된다.
구독자들은 이벤트(파티)에 관심 있으며 이벤트가 발생하면 특정 행동(파티 참석)을 취할 준비가 되어있다.
public class PartyHost
{
public delegate void PartyStartedEventHandler(string messgae);
public event PartyStartedEventHandler PartyStarted;
// === 초대장 발송 ===
// 이벤트 발생 메서드
public void StartParty()
{
Console.WriteLine("Party is starting!");
OnPartyStarted("Come join us at the party!");
}
// 이벤트를 보호하고 발생시키는 메서드 => 초대장 발송.
protected virtual void OnPartyStarted(string message)
{
PartyStarted?.Invoke(message);
}
// === 초대장 발송 END ===
}
public class Friend
{
// 형태가 ParyHost의 PartyStartedEventHandler 와 같다.
public void RespondToInvitation(string message)
{
Console.WriteLine($"I'm coming to the party! Message: {message}");
}
}
internal class Program
{
static void Main(string[] args)
{
PartyHost host = new PartyHost();
Friend friend = new Friend();
// 이벤트 구독
host.PartyStarted += friend.RespondToInvitation;
// Host의 이벤트를 friend가 구독한다.
// 이벤트 발생
host.StartParty();
// 그럼 구독하고 있는 friend가 응답.
}
}