본문 바로가기
Programming/C#

c#_11 : 대리자와 이벤트

by 공부합시다홍아 2020. 6. 12.

대리자와 이벤트

 

대리자 

출장을 나온 김대리는 사장님께 급히 보고를 드릴 일이 있어 회사에 전화를 걸었습니다. 그런데 전화를 받은 사람은 사장님이 아닌 비서였습니다.

김대리는 비서에게 사장님이 돌아오면 전화를 부탁드린다고 메모를 남겼습니다. 잠시후 사장님은 비서의 메모를 받고 김대리에게 전화를 걸어 통화하였습니다.

위의 예에서 김대리가 비서에게 했던 부탁 ( 메모 ) 를 '콜백(CallBack)'이라고 한다. 대신 어떤 일을 해줄 코드를 두고, 이 코드가 실행할 세부코드는 컴파일 시점이 아닌 실행 시점에 부여하는 식입니다. 

C#에서 대리자는 바로 이 콜백을 구현하기 위해 사용됩니다. 누군가 대신해서 일해주는 것을 전문으로 하는 사람을 의미합니다. 

객체의 주소를 가리키는 "참조"를 알 것입니다. 대리자는 메소드에 대한 참조입니다. 대리자에 메소드의 주소를 할당한 후 대리자를 호출하면 이 대리자가 메소드를 호출합니다 

  • 한정자 delegate 반환 형식 대리자 이름 ( 매게 변수 목록 );

  • 대리자는 인스턴스가 아닌 형식(Type)입니다. 다시 말해 "대리자 형식"은 int,string과 같은 형식이며 메소드를 참조하는 그 무엇을 만들기 위해 "대리자 형식"의 인스턴스를 따로 만들어야합니다.

콜백 구현 과정

  1. 대리자를 선언한다.

  2. 대리자의 인스턴스를 생성한다. 인스턴스를 생성할 때는 대리자가 참조할 메소드를 매개 변수로 넘긴다.

  3. 대리자를 호출한다.

 

대리자는 왜 그리고 언제 사용하는 가

프로그래밍을 하다보면 "값"이 아닌 "코드" 자체를 매개변수로 넘기고자 할 때가 있습니다. 예를 들어 배열을 정렬하는 메소드를 만들 때 오름차순으로 만들지, 내림차순으로 만들지 아니면 특별한 계산식을 거쳐서 나오는 결과 순으로 정렬하도록 만들지 고민합니다. 

이 메소드가 정렬을 수행할 때 사용하는 비교루틴을 매개변수로 넣을 수 있으면 이런 고민은 메소드를 사용하는 프로그래머가 알아서 하라고 하면 됩니다.

바로 이럴 때 대리자가 사용됩니다. 대리자는 메소드에 대한 참조이므로, 비교 메소드를 참조할 대리자를 매개 변수로 받도록 정렬 메소들르 작성해 놓으면 문제가 해결됩니다. 

일반화 대리자

대리자는 보통의 메소드뿐 아니라 일반화 메소드도 참조할 수 있습니다. 물론 이 경우에는 대리자도 일반화 메소들르 참조할 수 있도록 형식 매개 변수를 이용하여 선언되어야합니다. 형식 매개 변수를 이용해서 대리자를 선언하는 요령은 메소드와 같습니다.

괄호 < > 사이에 형식 매개 변수를 넣어주면 됩니다.

IComparable<T>

System.Int32(int), System.Double(double) 을 비롯한 모든 수치 형식과 System.String(String)은 모두 IComparable을 상속해서 CompareTo() 메소드를 구현하고 있다. 이들 모두의 CompareTo() 메소드는 매개 변수가 자신보다 크면 -1, 같으면 0, 작으면 1을 반환합니다. 그래서 ASC()메소드가 a.CompareTo(b)를 호출하면 우리가 원하는 대로 오름차순 정렬에 필요한 비교 결과를 얻을 수 있습니다.

대리자 체인

대리자 체인이란 대리자 하나가 여러 개의 메소드를 동시에 참조할 수 있다는 것을 뜻합니다. 

여러 개의 메소드를 두 가지 함수를 통해서 데이터를 불러오고 뺄 수 있습니다.

+= 구문을 활용하여 데이터를 불러옵니다.

-= 구문을 활용하여 데이터를 빼내기도 합니다. 

+= 구문은 .Combine 이나 하나 하나 직접입력하는 방법이 있는 동시에 -=는 Remove() 메소드와 같은 역할을 합니다.

 

익명 메소드 

이름이 없는 메소드를 말합니다. 

  •  [ delegate int 이름 (int a, int b) ]

이렇게 선언한 대리자의 인스턴스를 만들고 이 인스턴스가 메소드의 구현이 담겨있는 코드 블록을 참조시킨다. 대리자의 인스턴스를 호출하면 자신이 참조하고 있는 코드를 실행하게 된다. 

익명 메소드는 자신을 참조할 대리자의 형식과 동일한 형식으로 선언되어야 합니다. 가령 대리자에서 반환 형식을 int로 선언했다면 익명 메소드로 int형식의 결과를 반환해야 하며, 대리자에서 int형식의 매개 변수 세 개를 받도록 선언했다면 익명 메소드도 역시 동일하게 매게 변수를 받도록 구현해야 합니다. 

 

이벤트 : 객체에 일어난 사건 알리기

프로그래밍 세계에서는 알람 시켸처럼 어떤 일이 생겼을 때 이를 알려주는 객체가 필요한 경우가 있다. 알람 시계처럼 특정 시간이 되었을 때 이를 알려주거나,

사용자가 버튼을 클릭했을 때 이를 알려주는 객체입니다. 

이런 객체를 만들 때 사용하는 것이 바로 이벤트(EVENT)입니다. 

이벤트의 동작 원리는 대리자와 거의 비슷합니다. 이벤트는 대리자를 event 한정자로 수식해서 만든다.

  • 이벤트를 선언하고 사용하는 절차

            1. 대리자를 선언합니다. 이 대리자는 클래스 밖에 선언해도 되고 안에 선언해도 됩니다.

            2. 클래스 내에 1에서 선언한 대리자의 인스턴스를 event 한정자로 수식해서 선언합니다. 

            3. 이벤트 핸들러를 작성합니다. 이벤트 핸들러는 1에서 선언한 대리자와 일치하는 메소드면 됩니다.

            4. 클래스의 인스턴스를 생성하고 이 객체의 이벤트에 3에서 작성한 이벤트 핸들러를 등록합니다.

            5. 이벤트가 발생하면 이벤트 핸들러가 호출됩니다.

 

728x90