[C#] Event (이벤트)

ssungho·2023년 7월 20일
0

💡 CSharp Study

목록 보기
5/7
post-thumbnail

💡 delegate의 단점

delegate 객체에 접근할 수 있다면 호출하는 부분도 누구나 호출할 수 있게 된다.

class Program
{
	// delegate OnClicked 선언
    delegate int OnClicked();

    static void ButtonPressed(OnClicked clickedFunction)
    {
        Console.WriteLine("버튼이 눌렸습니다..!");

        // 델리게이트에 등록된 함수 호출
        clickedFunction();
    }
    
    static int TestDelegate1()
    {
        Console.WriteLine("TestDelegate1 실행..!");
        return 0;
    }

    static void Main(string[] args)
    {
        OnClicked clicked = new OnClicked(TestDelegate1);

        clicked(); // clickedFunction 호출
    }
}

OnClicked라는 델리게이트는 ButtonPressed 함수가 호출될때 사용하기 위해 clickedFunction을 만들었는데 clicked();처럼 객체를 접근해 누구나 등록된 함수를 호출 할 수 있다는 문제가 생긴다.

clickedFunction이 중요하고 신중하게 호출되어야 하는 부분이였다면 문제가 된다.


💡 Event 이벤트

클래스 안에서 일어난 일을 미리 구독해둔 곳에 알린다.

📌 델리게이트와의 차이점

선언된 클래스 내에서만 호출할 수 있고 외부에서는 함수의 등록만 가능하다.


📌 선언 방법

[접근 한정자] event [이벤트 핸들러] [이벤트 이름]

  • ex) public event OnInputKey InputKey;

📝 InputManager.cs

// Observer Pattern
class InputManager
{
    public delegate void OnInputKey(); // 델리게이트 선언
    public event OnInputKey InputKey; // 이벤트 선언

    public void Update()
    {
        if (Console.KeyAvailable == false)
        {
            return;
        }

        // 키보드의 키를 읽는 함수와 저장한 info
        ConsoleKeyInfo info = Console.ReadKey();
        {
            // info가 A라면, (입력받은 키가 키보드 A라면)
            if (info.Key == ConsoleKey.A)
            {
                // 이벤트 호출, 구독자에게 알린다.
                InputKey();
            }
        }
    }
}
  • 델리게이트와 이벤트의 접근 한정자를 동일하게 선언해야 한다.
    • 델리게이트가 public이라면 이벤트도 public으로 선언

  • 같은 클래스 내에서 호출이 가능하다.
    • InputManager클래스의 Update()에서 호출

  • 특정한 일이 일어났을 때 구독자가 있다면 구독자에게 사건을 알리는 방식을 옵저버 패턴이라고 한다.

📝 Program.cs

public class Program
{
    private static void OnInputTest()
    {
        Console.WriteLine("Input Received!");
    }

    private static void Main(string[] args)
    {
        // InputManager instance화
        InputManager inputManager = new InputManager();
        // InputKey에 OnInputTest구독
        inputManager.InputKey += OnInputTest;

        while (true) 
        {
            inputManager.Update();
        }
    }
}
  • InputManager를 사용하기 위해 객체화하여 참조한다.
    • InputManager inputManager = new InputManager();

  • InputKey에 OnInputTest를 구독한다.
    • OnInputKey와 반환타입이 같은 타입인 OnInputTest를 구독한다.
    • inputManager.InputKey += OnInputTest;

  • A키를 입력하면 Update()가 실행중이기 때문에 InputKey가 호출되어 OnInputTest()가 실행된다.

  • 직접적으로 선언된 클래스 외부에서 호출할 수 없다.

    • InputKey가 선언된 InputManager 밖인 Program에서 바로 호출할 수 없다.

📝 정리

이벤트는 델리게이트와 다르게 선언된 클래스에서만 호출할 수 있고, 외부에서 호출할 수 없다.


인프런 [C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part1: C# 기초 프로그래밍 입문 강의를 듣고 공식 문서를 참고하여 정리한 글 입니다.

개인 공부를 정리한 글이기 때문에 틀린 부분이 있을 수 있습니다.

profile
클라이언트 개발자가 되는 그날까지 👊

1개의 댓글

comment-user-thumbnail
2023년 7월 20일

많은 도움이 되었습니다, 감사합니다.

답글 달기