대리자(Delegate)와 이벤트 - 2 (이벤트, 대리자와 이벤트의 차이)
A. 이벤트 : 객체에 일어난 사건 알리기
이벤트는 대리자를 event 한정자로 수식해서 만들기 때문에 동작원리는 대리자와 거의 비슷하다.
- 이벤트를 선언하고 사용하는 절차
Step 1. 대리자를 선언한다. 대리자는 클래스 밖에 선언해도되고, 안에 선언해도 된다.
delegate void EventHandler(string message);
Step 2. 클래스내에 1에서 선언한 대리자의 인스턴스를 event 한정자로 수식해서 선언한다.
class MyNotifier
{
public event EventHandler SomethingHappend;
public void DoSomething(int number)
{
int temp=number % 10;
if(temp!=0 && temp%3==0)
{
SomethingHappend(String.Format($"{number} : 짝");
}
}
}
Step 3. 이벤트 핸들러를 작성한다. 이벤트 핸들러는 1에서 선언한 대리자와 일치하는 메소드면 된다.
class MainApp
{
static public void MyHandler(string message)
{
Console.WriteLine(message);
}
}
Step 4. 클래스의 인스턴스를 생성하고, 이 객체의 이벤트에 3에서 작성한 이벤트 핸들러를 등록한다.
Class MainApp
{
static public void MyHandler(string message)
{
Console.WriteLine(message);
}
static void Main(string[] args)
{
MyNotifier notifier = new MyNotifier();
notifier.SomethingHappend += new EventHander(MyHandler);
for(int i=1;i<30;i++)
{
notifier.DoSomething(i);
}
}
}
Step 5. 이벤트가 발생하면 이벤트 핸들러가 호출된다.
B. 대리자와 이벤트의 차이
앞에서 봤듯이, 이벤트는 대리자에 event 키워드로 수식해서 선언한 것에 불과하다.
하지만, 이벤트와 대리자의 가장 큰 차이점은 이벤트는 외부에서 직접 사용할 수 없다는 데 있다. 이벤트는 public 한정자로 선언되어 있어도 자신이 선언된 클래스 외부에서는 호출이 불가능하다.
그러나 대리자는 public 또는 internal로 수식되어 있으면 클래스 외부에서라도 얼마든지 호출이 가능하다.
* 대리자와는 달리 이벤트가 호출될 수 없다는 사실은 견고한 이벤트 기반 프로그래밍에 대한 기대를 가능하게 한다.
예를 들어, 네트워크 상태 변화에 대한 사건을 알리는 클래스를 작성해서 동료에게 준 경우, 이벤트를 객체 외부에서 임의로 호출할 수 있게된다면 이 객체의 외부에서 허위로 네트워크 상태 변화 이벤트를 일으킬 수 있게된다. 이런 위협은 대리자가 아닌 이벤트라야 막을 수 있다.
따라서, 대리자는 콜백 용도로 사용하고, 이벤트는 객체의 상태 변화나 사건의 발생을 알리는 용도로 구분해서 사용해야한다.