클래스 내부 로직에서 발생하는 이벤트를 다른 클래스에 전달해야 하는 경우가 있다.
Car 클래스에 현재 위치를 나타내는 _position, 목적지 위치를 나타내는 _destination 변수가 있고, 1초에 1씩 현재 위치를 증가시켜 목적지까지 도달하게 하는 Drive 메소드가 정의되어 있다.
main 메소드에서는 Car 객체를 car라는 이름으로 목적지 위치를 3으로 주어 생성하고 car 객체의 Drive 메소드를 호출한다.
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 | class Program { static void Main(string[] args) { Car car = new Car(3); car.Drive(); } } class Car { private int _position; private int _destination; public Car(int destination) { _destination = destination; } public void Drive() { while (_position < _destination) { _position++; Thread.Sleep(1000); } } } |
어떤 경우에는, Drive 메소드에서 _position의 값이 바뀌는 때를 main 메소드에서 알아야 할 필요가 있다. 그러나 현재의 구조에서는 알 방법이 없다. 구조를 변경하고 _position 값을 반환하는 새로운 메소드를 구현하는 방법도 있겠지만, 이 경우에는 EventHandler를 사용하는 것이 적합하다.
EventHandler를 사용하기 위해 Car 클래스에 추가 되어야 할 부분은 다음과 같다.
MoveEvent라는 이름의 이벤트를 등록하고, 이벤트핸들러에서 사용되는 EventArgs 클래스를 Car클래스 안에 nested class로 선언한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Car { public event EventHandler<MoveEventHandlerArgs> MoveEvent; public class MoveEventHandlerArgs { public int Position { get; set; } public MoveEventHandlerArgs(int position) { Position = position; } } } |
그리고 Drive 메소드의 while문 안에서 이벤트를 발생시킨다.
1 2 3 4 5 6 | while (_position < _destination) { _position++; if (MoveEvent != null) MoveEvent(this, new MoveEventHandlerArgs(_position)); Thread.Sleep(1000); } |
main 메소드에서는 car 객체의 MoveEvent 변수에 메인 클래스에서 정의한 이벤트핸들러 메소드를 추가해준다.
전체 코드는 다음과 같다.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | class Program { static void Main(string[] args) { Car car = new Car(3); car.MoveEvent += Move; car.Drive(); } private static void Move(object sender, Car.MoveEventHandlerArgs e) { Console.WriteLine(e.Position); } } class Car { private int _position; private int _destination; public Car(int destination) { _destination = destination; } public void Drive() { while (_position < _destination) { _position++; if (MoveEvent != null) MoveEvent(this, new MoveEventHandlerArgs(_position)); Thread.Sleep(1000); } } public event EventHandler<MoveEventHandlerArgs> MoveEvent; public class MoveEventHandlerArgs { public int Position { get; set; } public MoveEventHandlerArgs(int position) { Position = position; } } } |