일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- c# 추상 클래스
- Flutter
- vim
- dart 언어
- docker
- 다트 언어
- HTML
- Houdini
- Unity
- 도커
- C# delegate
- c# winform
- github
- jupyter
- C언어 포인터
- gitlab
- 유니티
- 깃
- Data Structure
- c#
- c# 윈폼
- Python
- git
- jupyter lab
- c언어
- 구조체
- 포인터
- 플러터
- C++
- Algorithm
- Today
- Total
nomad-programmer
[Programming/C#] 이벤트 (Event) : 객체에 일어난 사건 알리기 본문
알람 시계처럼 어떤 일이 생겼을 때 이를 알려주는 객체가 필요한 경우가 있다. 이런 객체를 만들 때 사용하는 것이 바로 "이벤트 (Event)" 이다.
이벤트의 동작 원리는 대리자와 거의 흡사하다. 이유는 이벤트는 대리자를 event 한정자로 수식해서 만들기 때문이다.
이벤트 선언 및 사용 절차
- 대리자 선언. 대리자는 클래스 밖에 선언해도 되고 안에 선언해도 된다.
- 클래스 내에 1에서 선언한 대리자의 인스턴스를 event 한정자로 수식하여 선언.
- 이벤트 핸들러를 작성. 이벤트 핸들러는 1에서 선언한 대리자와 일치하는 메소드면 된다.
- 클래스의 인스턴스를 생성하고 이 객체의 이벤트에 3에서 작성한 이벤트 핸들러를 등록한다.
- 이벤트가 발생하면 이벤트 핸들러가 호출된다.
이벤트 예제
using System;
namespace test
{
// 1. 대리자 선언. 대리자는 클래스 밖에 선언해도 되고 안에 선언해도 된다.
delegate void EventHandler(string message);
class MyNotifier
{
// EventHandler는 1에서 선언한 대리자이다.
public event EventHandler SomethingHappened;
public void DoSomething(int number)
{
int temp = number % 10;
if (temp != 0 && (temp % 3) == 0)
{
// numer가 3, 6, 9로 끝나는 값이 될 때마다 이벤트가 발생한다.
SomethingHappened(String.Format("{0} : 박수!", number));
}
}
}
internal class Program
{
// SomethingHappened 이벤트에서 사용할 이벤트 핸들러는 EventHandler 대리자의 형식과
// 동일한 메소드여야 한다.
static public void MyHandler(string message)
{
Console.WriteLine(message);
}
public static void Main(string[] args)
{
// SomethingHappened 이벤트에 MyHandler() 메소드를 이벤트 핸들러로 등록한다.
MyNotifier notifier = new MyNotifier();
notifier.SomethingHappened += new EventHandler(MyHandler);
for (int i = 0; i < 30; i++)
{
notifier.DoSomething(i);
}
}
}
}
/* 결과
3 : 박수!
6 : 박수!
9 : 박수!
13 : 박수!
16 : 박수!
19 : 박수!
23 : 박수!
26 : 박수!
29 : 박수!
*/
이벤트는 이벤트 처리기를 등록하지 않아도 컴파일 에러가 발생하지 않는다. 그리하여 초기화 하지 않은 이벤트를 쉽게 놓칠 수 있다. 때문에 이벤트를 선언하면 항상 비어 있는 익명 메소드로 미리 초기화를 해두는 것이 좋다. 최악의 경우에도 프로그램이 다운되는 것을 막을 수 있다.
대리자와 이벤트
이벤트는 대리자에 event 키워드로 수식해서 선언한 것에 불과하다. 하지만 다른점이 존재한다. 그것은 이벤트가 대리자와 다르게 외부에서 직접 사용할 수 없다는데 있다.
이벤트는 public 한정자로 선언되어 있어도 자신이 선언되어 있는 클래스 외부에서는 호출이 불가능하다. 반면 대리자는 public이나 internal로 수식되어 있으면 클래스 외부에서라도 얼마든지 호출이 가능하다.
이벤트가 대리자와는 달리 이벤트가 호출될 수 없다는 사실은 견고한 이벤트 기반 프로그래밍에 대한 기대를 가능하게 한다. 예를 들어 외부에서 이벤트를 마구잡이로 발생시킨다고 가정하면 이는 객체의 상태를 허위로 나타내는 것이다. 이런 위협은 대리자로는 막을 수 없다. 이벤트라야 가능하다.
따라서 대리자는 대리자대로 콜백 용도로 사용하고, 이벤트는 이벤트대로 객체의 상태 변화나 사건의 발생을 알리는 용도로 구분하여 사용해야 한다.
'Programming > C#' 카테고리의 다른 글
[Programming/C#] Func 대리자, Action 대리자 (0) | 2020.09.23 |
---|---|
[Programming/C#] Lambda (익명 메소드) (0) | 2020.09.23 |
[Programming/C#] delegate를 이용한 익명 메소드 (Anonymous Method) (0) | 2020.09.22 |
[Programming/C#] 대리자 체인 (0) | 2020.09.22 |
[Programming/C#] 일반화 대리자 (0) | 2020.09.22 |