Programing/C#

C# 프로그래밍의 기초 : 이벤트(Event)와 EventArgs

유니얼 2024. 3. 3. 18:30
728x90

C# 프로그래밍에서 이벤트는 객체나 클래스가 특정 상황에 발생했을 때 다른 객체에 알리는 강력한 방법을 제공합니다. 이 블로그 포스트에서는 C#의 이벤트 메커니즘과 EventArgs 클래스의 활용 방법을 설명하고, 이를 통해 어떻게 객체 간의 결합을 줄이고 코드의 유지보수성을 향상시킬 수 있는지 알아보겠습니다.

이벤트(Event)의 핵심 개념

이벤트는 대리자(delegate)를 기반으로 구현됩니다. 이벤트를 발생시키는 클래스를 '발행자(Publisher)'라 하고, 이벤트에 반응하여 처리를 수행하는 메서드를 가진 클래스를 '구독자(Subscriber)'라 합니다. 발행자는 특정 이벤트가 발생했음을 알리고, 구독자는 이 이벤트에 대해 정의된 작업을 수행합니다.

이벤트의 주요 특징

  • 캡슐화: 이벤트는 외부에서 직접 호출할 수 없으며, 이벤트를 정의한 클래스 내에서만 발생시킬 수 있습니다. 이는 클래스의 내부 로직을 보호하고, 외부에서의 무분별한 이벤트 발생을 방지합니다.
  • 구독 및 해지: 클래스 외부에서는 이벤트에 대한 구독을 통해 이벤트 발생 시 호출될 메서드를 등록할 수 있습니다. 구독자는 이벤트가 더 이상 필요 없을 때 구독 해지를 할 수 있습니다.
  • 알림 메커니즘: 이벤트는 클래스나 객체가 외부에 특정 상황을 알릴 필요가 있을 때 사용됩니다. 이는 프로그램의 다양한 부분이 서로 정보를 교환하고 반응할 수 있게 합니다.

EventArgs 클래스

EventArgs는 이벤트와 함께 데이터를 전달할 수 있는 클래스의 기본 형태입니다. 기본적으로는 데이터를 포함하지 않지만, 필요에 따라 EventArgs를 상속받아 추가 데이터를 포함하는 사용자 정의 클래스를 생성할 수 있습니다.

사용자 정의 EventArgs 예제:

public class ButtonEventArgs : EventArgs
{
    public string Message { get; private set; }

    public ButtonEventArgs(string message)
    {
        Message = message;
    }
}

이벤트 사용 예제

아래 예제는 사용자 정의 이벤트 RaiseCustomEvent를 발생시키는 간단한 발행자 클래스와 이 이벤트에 반응하여 메시지를 출력하는 구독자 클래스의 상호 작용을 보여줍니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace CSharp_ProgramingStudy.Chapter7_Extension
{
    public class Class6
    {
        /// <summary>
        /// ButtonEventArgs 클래스는 EventArgs를 상속받아 추가적인 메시지 데이터를 포함하는 예제입니다.
        /// </summary>
        public class ButtonEventArgs : EventArgs
        {
            public string Message;

            public ButtonEventArgs(string message)
            {
                Message = message;
            }
        }

        /// <summary>
        /// Button 클래스는 간단한 이벤트를 정의하는 예제로, ButtonClicked 이벤트를 발생시킵니다.
        /// </summary>
        public class Button
        {
            // 이벤트 선언: 버튼이 클릭되었음을 알리는 이벤트
            public event EventHandler<ButtonEventArgs> ButtonClicked;

            // 버튼 클릭 메서드
            public void Click()
            {
                Console.WriteLine("Button was clicked!");

                // 이벤트 발생
                OnButtonClicked(new ButtonEventArgs("Button Clicked!"));
            }

            // 이벤트 발생 메서드
            protected virtual void OnButtonClicked(ButtonEventArgs e)
            {
                // 이벤트가 구독된 경우에만 실행
                if (ButtonClicked != null)
                {
                    ButtonClicked(this, e);
                }
            }
        }

        /// <summary>
        /// Subscriber 클래스는 버튼의 클릭 이벤트를 구독하는 예제입니다.
        /// </summary>
        public class Subscriber
        {
            private string name;

            // 생성자에서 버튼의 클릭 이벤트를 구독
            public Subscriber(string name, Button button)
            {
                this.name = name;
                button.ButtonClicked -= HandleButtonClick;
                button.ButtonClicked += HandleButtonClick;
            }

            // 이벤트 핸들러 메서드: 버튼이 클릭되었을 때 실행
            void HandleButtonClick(object sender, ButtonEventArgs e)
            {
                Console.WriteLine($"{name} received the ButtonClicked event with message: {e.Message}");
            }
        }

        public static void Run()
        {
            // 버튼 인스턴스 생성
            Button button = new Button();

            // 두 구독자(Subscriber) 생성 및 버튼 클릭 이벤트 구독
            Subscriber sub1 = new Subscriber("Subscriber 1", button);
            Subscriber sub2 = new Subscriber("Subscriber 2", button);

            // 버튼 클릭
            button.Click();
        }
    }
}

이 예제에서 Button 클래스는 클릭 이벤트를 발생시키고, Subscriber 클래스는 이 이벤트를 구독하여 클릭 시 메시지를 출력합니다. 이벤트와 EventArgs를 사용함으로써 발행자와 구독자 사이의 의존성이 줄어들며, 코드의 유연성과 재사용성이 향상됩니다.

결론

C#의 이벤트와 EventArgs 클래스는 객체 지향 프로그래밍에서 효율적인 객체 간의 소통을 가능하게 하는 중요한 도구입니다. 이벤트를 적절히 활용하면, 다양한 시나리오에서 객체의 상호작용을 유연하고 효과적으로 관리할 수 있습니다.

반응형