Chapter.13 대리자와 이벤트
1. 대리자(Delegate)
> 사용자의 메서드 호출을 콜백(Callback)이라고 하는데, 이러한 콜백을 통해 메서드를 대신 호출해주는 역할을 대리자가 한다.
> 근본적인 사용 이유는 메서드를 참조하여 실행 로직을 전부 넘기고 싶을 때 사용한다.
1) 기본문법
한정자 delegate 반환형 대리자(매개변수);
public delegate int MyDelegate(int a, int b);
int def(int a, int b)
{
return 0;
}
▲ 대리자는 사용할 메서드와 반환형, 매개변수가 같아야 함.
2) 사용법
delegate int Compare(int a, int b); // 대리자 선언
static int Ascend(int a, int b) // 대리자와 형식이 같은 메서드 정의
{
if (a > b) return 1;
else if (a == b) return 0;
else return -1;
}
static void BubbleSort(int[] Data, Compare Comparer) // 대리자를 사용하는 정렬 메서드 정의
{
int temp = 0;
for (int i=0; i<Data.Length - 1; i++)
{
for (int j = 0; j < Data.Length - (i + 1); j++)
{
if (Comparer(DataSet[j], DataSet[j + 1]) > 0) // 대리자 객체 사용
{
temp = Data[j + 1];
Data[j + 1] = Data[j];
Data[j] = temp;
}
}
}
}
int[] arr = {3, 7, 4, 2, 10};
// Compare Comparer = new Compare(Ascend), 대리자에게 Ascend 콜백을 넘김
BubbleSort(arr, new Compare(Ascend));
▲ 정렬 메서드 로직에서 활용되는 건 대리자 객체(Comparer)이고, 정렬 메서드의 인수로 실제 메서드(Ascend)를 넘기면 대리자 객체는 실제 메서드를 참조하여 호출하게 된다.
2. 일반화 대리자
> 대리자는 일반화 메서드도 참조할 수 있음.
1) 기본문법
delegate int Compare<T>(T a, T b); // 대리자도 형식 매개변수를 사용해야 함
2) 사용법
delegate int Compare<T>(T a, T b); // 일반화 대리자 선언
static int Ascend<T>(T a, T b) // 일반화 메서드 선언
{
if (a > b) return 1;
else if (a == b) return 0;
else return -1;
}
static void BubbleSort<T>(T[] Data, Compare<T> Comparer) // 대리자를 사용하는 정렬 메서드도 일반화
{
T temp;
for (int i = 0; i < Data.Length - 1; i++)
{
for (int j = 0; j < Data.Length - (i + 1); j++)
{
if (Comparer(Data[j], Data[j + 1]) > 0) // 내부로직은 똑같음.
{
temp = Data[j + 1];
Data[j + 1] = Data[j];
Data[j] = temp;
}
}
}
}
stirng[] arr = {"abc", "def", "ghi", "jki", "mno"};
BubbleSort<string>(arr, new Compare<string>(Ascend)); // 문법에 맞게 형식 매개변수를 넣음
3. 대리자 체인
> 대리자 객체가 여러개의 메서드를 참조할 수 있도록 하는 것
delegate void ThereIsFire(string location); // 대리자 생성
void Call(string location) // 대리자 형식을 맞춘 메서드 1
{
Console.WriteLine("소방서에 신고, 주소 : {0}", location);
}
void Escape(string location) // 대리자 형식을 맞춘 메서드 2
{
Console.WirteLine("{0}에서 탈출", location);
}
ThereIsFire Fire = new ThereIsFire(Call); // 대리자 객체 생성과 동시에 Call 메서드를 참조하는 콜백 전달
Fire += new ThereIsFire(Escape); // += 연산자를 통해 전달
Fire -= new ThereIsFire(Call); // -= 연산자를 통해 제거
▲ 연산자를 통해 메서드 참조 전달
ThereIsFire Fire = (ThereIsFire) Delegate.Combine(new ThereIsFire(Call), new ThereIsFire(Escape));
▲ Delegate.Combine() 메서드를 사용해서 전달
4. 익명 메서드
> 익명 메서드는 대리자 객체가 임시적으로 참조할 때 사용하는 메서드이다.
대리자 객체 = delegate(매개변수)
{
...
}
delegate int Caculate(int a, int b);
Calculate cal;
cal = delegate(int a, int b) // 익명 메서드
{
return a + b;
}
5. 이벤트(Event)
> 이벤트는 대리자(delegate)를 기반으로 하여 대리자 객체를 호출할 때마다 대리자처럼 실제 메서드를 참조하는 콜백을 실행시킴
1) 기본문법
class 클래스
{
한정자 event 대리자형식 대리자객체;
}
delegate void Del(string str); // 대리자를 기반으로 함
class MyClass
{
public event Del Something; // event 키워드로 대리자 객체를 감싼다
}
2) 사용법
delegate void EventHandler(string message); // 대리자 생성
class MyClass
{
public event EventHandler Something; // 이벤트 생성
private int count = 0;
public void DoSomething()
{
count++;
Something($"{count}번쨰 호출됨");
}
}
class MainApp
{
static public void Handler(string message) // 이벤트 구독 메서드 정의
{
Console.WriteLine(message);
}
static void Main(string[] args)
{
MyClass Mine = new MyClass();
Mine.Something += Handler; // 이벤트 구독
// 이벤트 호출
Mine.DoSomething(); // 1번째 호출됨
Mine.DoSomething(); // 2번째 호출됨
}
}
> 대리자 선언
> event 키워드로 이벤트 생성
> 이벤트 구독 메서드 정의
> 이벤트 호출
> 이벤트 호출
3) 추가
static public void Handler(string message) // 이벤트 구독 메서드 정의
{
Console.WriteLine(message);
}
▲ 만약 이 부분을
static public void Handler(string message) // 이벤트 구독 메서드 정의
{
Console.WriteLine(message);
Console.WriteLine(message);
}
▲ 위처럼 변경하게 된다면
1번째 호출됨
1번째 호출됨
2번째 호출됨
2번째 호출됨
처럼 출력된다.
'LMS 7 > 개발일지' 카테고리의 다른 글
| 25.09.30 개발일지 / C# 4(1) (Chapter19) (0) | 2025.11.11 |
|---|---|
| 25.09.30 개발일지 / C# 클래스 (0) | 2025.11.11 |
| 25.09.29 개발일지 / C# 2(3) (Chapter11, Chapter12) (0) | 2025.11.11 |
| 25.09.28 개발일지 / C# 2(2) (Chapter09, Chapter10) (0) | 2025.11.11 |
| 25.09.27 개발일지 / C# 2(1) (Chapter07, Chapter08) (0) | 2025.11.11 |