Menu
Coddy logo textTech

델리게이트와 이벤트

Coddy C# 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 70개 중 43번째.

delegate는 메서드에 대한 참조를 나타내는 형식입니다. 데이터를 저장하는 대신 메서드를 저장하는 변수라고 생각하면 됩니다. 이를 통해 메서드를 인수로 전달하고, 컬렉션에 저장하며, 동적으로 호출할 수 있습니다.

참조할 수 있는 메서드 시그니처를 지정하여 delegate를 선언합니다:

public delegate void Notify(string message);

public class Publisher
{
    public void SendAlert(string msg) => Console.WriteLine("Alert: " + msg);
}

// 사용법
Notify notifier = new Publisher().SendAlert;
notifier("System started");  // Alert: System started

이벤트는 게시-구독 pattern을 구현하기 위해 대리자를 기반으로 합니다. 하나의 class가 event를 raises하면 다른 class가 알림을 받도록 구독할 수 있습니다. event 키워드는 대리자를 사용할 수 있는 방식을 제한합니다. 구독자는 handler를 추가하거나 제거할 수만 있으며 event를 직접 호출할 수는 없습니다.

public class Button
{
    public event Action Clicked;
    
    public void Click()
    {
        Clicked?.Invoke();  // 모든 구독자에게 알림
    }
}

// 구독
Button btn = new Button();
btn.Clicked += () => Console.WriteLine("Button was clicked!");
btn.Click();  // 버튼이 클릭되었습니다!

+= 연산자는 handler를 Subscribe하고, -=는 Subscribe를 해제합니다. ?.Invoke() pattern은 subscribers가 있는 경우에만 event를 safely 호출합니다. event는 GUI 애플리케이션, 게임 엔진 및 객체가 강한 결합 없이 변경에 반응해야 하는 모든 시스템의 기본 요소입니다.

challenge icon

챌린지

쉬움

온도가 변경될 때마다 delegates와 event를 사용하여 subscribers에게 알림을 보내는 온도 모니터링 시스템을 만들어 보겠습니다. 이는 event가 매우 우아하게 가능하게 하는 publish-subscribe pattern의 전형적인 예입니다.

코드를 두 개의 파일로 구성합니다:

  • TemperatureMonitor.cs: publisher 역할을 하는 TemperatureMonitor class를 Monitoring namespace에 만듭니다. monitor는 다음을 수행해야 합니다:
    • current 온도를 저장할 private field를 가집니다
    • 온도가 업데이트될 때마다 발생하는 Action<int>을 사용하는 TemperatureChanged event를 Declare합니다
    • Temperature property (int)를 가지며, setter는 private field를 업데이트하고 새로운 온도 값과 함께 event를 raise합니다
    subscribers가 있을 때만 event를 safely raise하도록 ?.Invoke() pattern을 사용하는 것을 잊지 마세요.
  • Program.cs: main 파일에서 TemperatureMonitor를 만들고 해당 TemperatureChanged event에 서로 다른 두 handler를 Subscribe합니다:
    • 다음을 prints하는 하나의 handler: Alert: Temperature is now {value} degrees
    • 다음을 prints하는 또 다른 handler: Logged: {value}
    두 handler를 모두 Subscribe한 후 input에서 받은 값을 사용하여 온도를 두 번 설정합니다. 온도를 설정할 때마다 두 handler가 모두 응답해야 합니다.

두 개의 input을 받습니다:

  • 첫 번째 온도 값 (정수)
  • 두 번째 온도 값 (정수)

예를 들어 input이 2530이면 output은 다음과 같아야 합니다:

Alert: Temperature is now 25 degrees
Logged: 25
Alert: Temperature is now 30 degrees
Logged: 30

Temperature property를 설정하면 모든 subscribers에게 자동으로 Notify한다는 점에 주목하세요. monitor는 누가 수신하고 있는지 전혀 알 필요가 없습니다. 이것이 바로 event-driven 접근 방식의 장점입니다!

직접 해보기

using System;
using Monitoring;

class Program
{
    public static void Main(string[] args)
    {
        // 입력 읽기
        int temp1 = Convert.ToInt32(Console.ReadLine());
        int temp2 = Convert.ToInt32(Console.ReadLine());

        // TODO: TemperatureMonitor 인스턴스 생성

        // TODO: Subscribe a handler that prints: "Alert: Temperature is now {value} degrees"

        // TODO: "Logged: {value}"를 출력하는 다른 핸들러 구독

        // TODO: 온도를 temp1로 설정

        // TODO: 온도를 temp2로 설정
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 C# 컴파일러