이 글을 읽는 당신이 만약 C#을 좀 하시는 분들이라면 "델리게이트와 액션"을 사용해보셨을 겁니다.
그리고 이 둘을 배울 때 항상 같이 배우는 녀석이 있는데요. (like. 마트 2+1 행사마냥 엌)
바로 "event"라는 키워드입니다.
public event Action MyAction;
이 키워드는 델리게이트 앞에 붙을 수 있으며 이 키워드는 2가지 역할을 수행하며 저 2가지말고도 어떠한 영향을 끼치는지 알아보겠습니다.
1. 외부에서의 호출을 막는다. 😡
event키워드는 외부에서 호출, 즉 Invoke시키는 것을 막아줍니다.
public class GameManager : MonoSingleton<GameManager>
{
public event Action OnPlayerDeath;
public void PlayerDie()
{
OnPlayerDeath?.Invoke();
}
}
public class TestClass
{
void Start()
{
GameManager.Instance.OnPlayerDeath?.Invoke(); //에러가 뜬다. (자동완성에 Invoke자체가 안뜸)
}
}
위와 같은 예시코드처럼 외부로부터 이벤트가 호출되는 것을 막아주며
예시상황으로, 게임의 상태를 관리하는 메니저가 있고 이 메니저의 OnGameStatusClear라는 액션을 구독하고 있는 녀석들이 있다고 쳤을 때 외부에서 이 이벤트를 호출해버리면 갑작스럽게 게임이 초기화되는 상황이 일어나는 것처럼 캡슐화를 해주는 것입니다.
2. 외부에서 = 으로 덮어씌울 수 없다. 🤬🤬
public class HumanErrorTroll : MonoBehaviour
{
void Start()
{
GameManager.Instance.OnPlayerDeath = HandleTroll; //에러가 뜬다.
}
private void HandleTroll()
{
//휴먼에러;;;;;;
}
}
event 키워드를 붙이면 외부에서 구독(+=), 해제(-=)만 가능해지며 =로 구독리스트들을 덮어씌워버리는 것을 막아줍니다.
예시상황으로, 앞 상황처럼 게임의 상태를 관리하는 매니저가 있고 OnGameStatusClear라는 액션에 구독되어있는 녀석들이 개발자의 실수로 외부에서 null을 넣어 구독되어있는 녀석들 모두를 해체해버리는 코드를 넣어 게임의 버그를 발생시키는 등의 상황을 방지할 수 있습니다.
이처럼 event는 이 2가지 역할을 합니다.
하지만 event가 선언한 "변수" 자체에 개입을 하기도하는데요.
이런 코드 보신 적 있을 겁니다.
public interface ITestInterface
{
event Action OnTestAction;
}
인터페이스에서 액션을 선언하여 구현 멤버로써 사용하는 코드인데요.
여기서 event키워드를 빼면 오류가 뜨며 "인터페이스는 인스턴스 필드를 포함할 수 없습니다." 라고 뜹니다.
아시다시피 인터페이스는 필드를 포함하지못하지만 이거랑 event랑 무슨 상관일까요?
event가 붙게되면 액션은 "프로퍼티"처럼 작동하며 내부적으로 프로퍼티와 같은 접근자 add/remove가지게 됩니다.
private Action _onTestAction;
public event Action OnTestAction
{
add { _onTestAction += value; } // += 할 때
remove { _onTestAction -= value; } // -= 할 때
}
그리고 인터페이스는 프로퍼티를 가질 수 있기 때문에 event를 붙여야만 인터페이스에 작성할 수 있는것이며, 외부에는 add와 remove만 접근할 수 있도록 되어있고 =와 호출은 접근자로 노출되어있지 않기 때문에 못하는 것입니다.
이상입니다.
'개발관련 > C# (중급)' 카테고리의 다른 글
| [C#] Discard 무시 항목 "_"🤓 (0) | 2026.03.08 |
|---|