TIL
[TIL] C# 이벤트(Event)란?
DearGreen
2024. 10. 7. 21:56
C# 이벤트(Event)란?
C#의 이벤트는 객체 간의 통신을 가능하게 하고, 특정 행동이나 상태 변화에 대한 반응을 정의한다. 대리자는 이러한 이벤트를 다루기 위한 중요한 구성 요소이다.
이번 글에서는 C#의 이벤트와 대리자의 개념을 정리하고, 대리자가 어떻게 유용하게 사용될 수 있는지를 살펴보자.
대리자에 대한 설명은 지난 포스트를 첨부한다.
https://deargreen.tistory.com/31
[TIL] C# 대리자(Delegate)란?
C# 대리자(Delegate)란? C#의 대리자에 대해 알아보자. 마이크로소프트 사의 C# 공식 문서를 참고해 알아보자. [대리자(Delegate) 란?]대리자는 특정 매개 변수 목록 및 반환 형식이 있는 메서드에 대
deargreen.tistory.com
여기에 덧붙여, 대리자를 어떤 상황에서 유용하게 사용하는지 정리해 보자.
[대리자를 유용하게 사용하는 상황]
1. 이벤트 처리 :
- 이벤트가 발생하면 관련된 대리자를 통해 특정 메서드가 호출된다. 예를 들어, 버튼 클릭 이벤트에서 클릭한 후의 동작을 정의할 수 있다.
2. 비동기 프로그래밍 :
- 비동기 작업을 수행할 때 대리자를 사용하여 비동기 메서드를 호출하고 완료할 때 사실을 알릴 수 있다.
3. 콜백 매서드 :
- 특정 작업이 완료되었을 때 자동으로 호출되는 메서드를 지정할 수 있다. 이는 발행자(Publisher) - 구독자(Subscriber) 모델을 통해 기능을 확장하는 데 유용하다.
- 서브스크립션 모델? :
서브스크립션 모델은 객체 간의 통신 방식 중 하나로, 특정 이벤트가 발생했을 때 이를 알리기 위해 구독자(Subscriber)가 이벤트를 등록하는 구조이다. 이 모델은 주로 이벤트 기반 프로그래밍에서 사용된다.
[이벤트란?]
: C#의 이벤트는 객체 간 통신을 가능하게 하며, 특정 행동이나 상태 변화에 대한 반응을 정의한다. 이벤트는 대리자(delegate)를 통해 처리되며, 대리자는 특정 매개변수와 반환 형식을 가진 메서드에 대한 참조를 제공한다. 이 구조는 이벤트 기반 프로그래밍에서 효율적인 메시지 전달을 가능하게 한다.
[이벤트의 구성 요소]
- 대리자(delegate) : 이벤트를 처리할 메서드를 참조하는 데 사용된다.
- 이벤트 핸들러(EventHandler) : 이벤트가 발생했을 때 호출되는 메서드이다.
[대리자와의 차이점은?]
=> 선언 위치 / 접근성이 다르다.
[선언 위치]
- 이벤트 : 인터페이스 내부에서 선언할 수 있다! 이는 이벤트가 인터페이스의 일부로서 구현될 수 있도록 한다.
- 대리자 : 대리자는 클래스나 네임스페이스 내에서 선언할 수 있지만, 인터페이스 내부에서는 선언할 수 없다.
[접근성]
- 이벤트: 이벤트는 public으로 선언되더라도 해당 이벤트가 정의된 클래스 외부에서 직접 호출할 수 없다. 이는 이벤트의 안정성을 높이고, 객체의 상태 변화에 대한 제어를 강화한다.
- 대리자: 대리자는 호출이 가능하며, 외부에서 직접 메서드를 참조하고 호출할 수 있다.
using System;
// 1. 대리자 선언: 특정 매개변수와 반환 형식을 가진 메서드를 참조할 수 있는 타입
public delegate void MyDelegate(string message);
// 2. 클래스 정의
public class MyClass
{
// 3. 이벤트 선언: 대리자를 기반으로 하는 이벤트
public event MyDelegate MyEvent;
// 4. 이벤트를 발생시키는 메서드
public void TriggerEvent(string message)
{
// 5. 이벤트가 구독되어 있으면 호출
MyEvent?.Invoke(message); // Null 조건 연산자를 사용하여 안전하게 호출
}
}
// 6. 구독자 클래스 정의
public class Subscriber
{
// 7. 이벤트 핸들러: 이벤트 발생 시 호출될 메서드
public void OnMyEvent(string message)
{
Console.WriteLine($"이벤트 발생: {message}");
}
}
// 8. 프로그램 실행
public class Program
{
public static void Main()
{
MyClass myClass = new MyClass(); // 9. 발행자 인스턴스 생성
Subscriber subscriber = new Subscriber(); // 10. 구독자 인스턴스 생성
// 11. 이벤트 구독: MyEvent가 발생할 때 OnMyEvent 메서드를 호출하도록 설정
myClass.MyEvent += subscriber.OnMyEvent;
// 12. 이벤트 발생: 메시지를 전달하여 이벤트를 트리거
myClass.TriggerEvent("Hello, World!");
// 13. 이벤트 구독 해제 (선택적)
myClass.MyEvent -= subscriber.OnMyEvent; // 구독 해제
}
}
위 코드는 대리자와 이벤트를 사용한 간단한 예시이다. 13번 주석의 구독 해제가 중요한 점이 무엇일까?
- 이벤트에 구독된 메서드는 발행자 객체가 살아 있는 동안 참조를 유지한다(즉, 메모리를 유지한다). 만약 구독자가 더 이상 필요하지 않거나, 프로그램의 흐름에서 더 이상 호출되지 않는 경우에도 구독이 유지되면 메모리 누수가 발생할 수 있다! 상황에 따른 적절한 구독 해제를 통해 메모리 사용을 최적화할 수 있다!