C#에 delegate와 event가 뭔가요?
튜터 활동을 하면서 이와 같은 질문을 받았다.
게임 개발을 하면서 델리게이트와 이벤트는 너무 중요한 개념이다.
실제로도 사용을 많이 하지만 막상 설명을 하려하니 설명하기가 쉽지 않다.
델리게이트와 이벤트는 개념에 대한 이해보다는 실제 적용 사례를 느껴보는게 좋다.
필자는 개인적으로 아래의 영상이 처음 공부를 할 때 도움이 많이 되었다.
https://youtu.be/m9_D0DQ4SGU
쉽게 설명하자면 delegate는 값이 아닌 '코드'자체를 넘기고 싶을 때 사용할 수 있다.
C#에서 메서드에 대한 참조 형식인데 함수를 매개변수로 전달하거나 반환 값으로 사용할 수 있게 해준다.
C++에 함수 포인터와 유사하다고 생각하면 된다. 아래의 예시를 보면 좀 더 쉽게 이해할 수 있다.
delegate void DelegateChain();
static void Print1()
{
Console.WriteLine("Welcome");
}
static void Print2()
{
Console.WriteLine("To");
}
static void Print3()
{
Console.WriteLine("C#");
}
static void Main(string[] args)
{
DelegateChain chaincall = new DelegateChain(Print1);
chaincall += Print2;
chaincall += Print3;
chaincall();
}
해당 코드를 보면 chaincall이라는 델리게이트에 Print1, Print2, Print3 등
여러개의 메소드를 동시에 참조하는 것을 볼 수있다.
이렇게 하면 chaincall 호출하면 참조하고 있는 Print1, Print2, Print3을 모두 호출한다.
이벤트는 특정 동작일 발생할 때 특정 기능을 실행할 수 있도록 한다.
실제로 Unity 개발을 하면서 아래와 같은 코드를 작성해줘야 하는 상황들이 많다.
public class Player
{
public delegate void PlayerDiedDelegate();
public event PlayerDiedDelegate PlayerDied;
public void Die()
{
if(PlayerDied != null)
PlayerDied();
}
}
public class GameManager
{
public void OnPlayerDied()
{
// 플레이어가 죽었을 때 실행할 로직
}
}
public class Main
{
public static void Main(string[] args)
{
Player player = new Player();
GameManager gameManager = new GameManager();
player.PlayerDied += gameManager.OnPlayerDied;
player.Die(); // OnPlayerDied 메서드가 호출됩니다.
}
}
player.PlayerDied 이벤트에 gameManager.OnPlayerDied 참조를 하여
PlayerDied()가 클래스 내부에서 호출되면 자동으로 gameManager.OnPlayerDied 코드가 실행이 된다.
앞서 배운 델리게이트와 쓰임새가 비슷하다. 그렇다면 둘의 차이점은 무엇일까?
델리게이트는 외부에서 직접 호출할 수 있지만 이벤트는 해당 클래스 내부에서만 호출할 수 있다.
이것은 이벤트 기반 프로그래밍에서 안정성을 추구하는 것이며 클래스 외부에서 이벤트에 변화를 줄 수 없게 하기 위함이다.
또한 델리게이트는 주로 코드의 재사용성과 유연성을 높이는데 사용되며, 이벤트는 특정 액션의 발생을 다른 객체에 알리는 데 사용된다. 추후 옵저버 패턴을 공부하는데도 중요한 내용이니 잘 숙지하길 바란다.