25.09.29 개발일지 / C# 3 (Chapter13)

2025. 11. 11. 10:53·LMS 7/개발일지

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
'LMS 7/개발일지' 카테고리의 다른 글
  • 25.09.30 개발일지 / C# 4(1) (Chapter19)
  • 25.09.30 개발일지 / C# 클래스
  • 25.09.29 개발일지 / C# 2(3) (Chapter11, Chapter12)
  • 25.09.28 개발일지 / C# 2(2) (Chapter09, Chapter10)
m_Dev
m_Dev
  • m_Dev
    m_Dev
    m_Dev
  • 전체
    오늘
    어제
    • 분류 전체보기
      • MAIN STUDY
        • 정보보안
        • 빅데이터
        • 정보처리
        • 컴퓨터 구조
        • 기타
      • JOB
        • Study
        • Project
      • LMS 7
        • 개발일지
      • FRAMEWORK
        • Qt
        • MFC
        • Winform
        • WPF
        • MAUI
      • NETWORK
        • Study
        • Assignment
      • PYTHON
        • Set
        • Study
        • Assignment
        • Project
      • C
        • Set
        • Study
        • Assignment
        • Project
      • C++
        • Set
        • Study
        • Assignment
        • Project
      • C#
        • Set
        • Study
        • Assignment
        • Project
      • DATABASE
        • MySQL
        • SQLite
      • IDE
        • VisualStudioCode
        • VisualStudio
        • Pycharm
        • Colab
      • 기타
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
m_Dev
25.09.29 개발일지 / C# 3 (Chapter13)
상단으로

티스토리툴바