`event` 키워드

event 키워드 (C# 참조)

출처: The event keyword (C# reference)

본문

이벤트(event)는 객체가 다른 쪽에 알림을 보낼 수 있게 해 주는 멤버예요. 이벤트를 이용하는 쪽에서는 이벤트 핸들러(event handler)를 붙여서, 이벤트가 일어날 때 실행할 코드를 등록하죠. event 키워드는 바로 이런 이벤트를 선언하는 키워드입니다. 이벤트는 델리게이트(delegate) 형식을 띠고 있어요. 객체가 이벤트를 발생시키면 등록된 모든 이벤트 핸들러가 호출되는데, 이벤트 핸들러는 이벤트에 추가된 델리게이트 인스턴스로서 이벤트가 발생(raise)될 때 실행됩니다. 이벤트를 쓰는 쪽에서는 자신의 이벤트 핸들러를 이벤트에 추가하거나 제거할 수 있어요.

아래 예시는 xref:System.EventHandler를 기본 델리게이트 형식으로 사용하는 이벤트를 선언하고 발생시키는 방법을 보여줍니다. 전체 코드 예시는 .NET 지침에 맞는 이벤트 게시 방법 문서에서 확인할 수 있어요. 그 예시에는 제네릭 xref:System.EventHandler`1 델리게이트 형식 사용법, 이벤트 구독 방법, 이벤트 핸들러 메서드를 만드는 방법까지 담겨 있습니다.

이벤트는 멀티캐스트 델리게이트이면서도, 우리가 이벤트를 선언한 클래스(또는 파생 클래스)나 구조체 안에서만 호출할 수 있는 특별한 델리게이트예요. 이벤트를 선언한 쪽이 게시자(publisher) 클래스가 되고, 다른 클래스나 구조체가 이벤트를 구독하면 게시자 클래스가 이벤트를 발생시킬 때 그들의 이벤트 핸들러 메서드가 호출되는 구조죠. 더 자세한 내용과 코드 예시는 EventsDelegates 문서에서 볼 수 있어요.

이벤트에는 public, private, protected, internal, protected internal, private protected 접근 한정자를 붙일 수 있습니다. 이 한정자들이 클래스 사용자가 이벤트에 어떻게 접근할 수 있는지를 정해요. 자세한 내용은 Access Modifiers 문서를 참고하세요.

C# 14부터는 이벤트를 partial로 선언할 수도 있어요. partial 이벤트는 정의(declaring) 선언 하나와 구현(implementing) 선언 하나를 갖는데, 정의 선언은 반드시 필드 형식(field-like) 구문을 써야 하고, 구현 선언에서는 addremove 핸들러를 선언해야 됩니다.

키워드와 이벤트

이벤트에 적용할 수 있는 키워드들을 나열해 볼게요.

  • static: 클래스의 인스턴스가 없어도 언제든 호출자가 이벤트를 사용할 수 있게 해 줘요. static 이벤트에 대한 자세한 내용은 Static Classes and Static Class Members 문서를 참고하세요.
  • virtual: 파생 클래스가 override 키워드를 사용해서 이벤트 동작을 재정의할 수 있게 해 줘요. virtual 이벤트에 대한 자세한 내용은 Inheritance 문서를 참고하세요.
  • sealed: 파생 클래스에서 더 이상 virtual이 아니게 만듭니다.
  • abstract: 컴파일러가 addremove 이벤트 접근자(accessor) 블록을 생성하지 않으므로, 파생 클래스가 자신만의 구현을 제공해야 합니다.

static 키워드를 쓰면 이벤트를 static 이벤트로 선언할 수 있어요. static 이벤트는 클래스 인스턴스가 없어도 언제든 호출자가 사용할 수 있고, 자세한 내용은 Static Classes and Static Class Members 문서를 참고합니다.

virtual 키워드로 이벤트를 virtual 이벤트로 표시할 수도 있어요. 파생 클래스는 override 키워드로 이벤트 동작을 재정의할 수 있죠. 자세한 내용은 Inheritance 문서를 참고하세요. virtual 이벤트를 재정의한 이벤트는 sealed로 만들 수도 있는데, 이러면 파생 클래스에서 더 이상 virtual이 아니게 돼요. 마지막으로 이벤트를 abstract로 선언할 수도 있어요. 이 경우 컴파일러가 addremove 이벤트 접근자 블록을 생성하지 않으므로, 파생 클래스가 자신만의 구현을 제공해야 합니다.

더 알아보기