CS 공부

[C#] 대리자 (Delegate)

때류기 2024. 7. 27. 00:38

1. 대리자란?

 

C#에서 대리자는(Delegate)는 특정 메서드를 참조하는 형식의 안전한 객체입니다. 이는 C++의 함수 포인터와 비슷하지만, 형식 안전성(type-safety)을 보장하고 객체 지향 프로그래밍 개념을 따릅니다. 대리자는 메서드를 변수처럼 다룰 수 있게 해주며, 메서드를 매개변수로 전달하거나 반환할 수 있게 해줍니다.

 

 

대리자의 선언 및 사용 방법

 

1. 대리자 선언

public delegate void MyDelegate(string message); //대리자 선언

 

2. 대리자 인스턴스 생성

MyDelegate del = new MyDelegate(MethodToCall);

 

3. 대리자 호출

del("Hello, World!");

 

4. 대리자를 통한 콜백 사용

public void MethodWithCallback(int param, MyDelegate callback)
{
    // Some operations
    callback("Callback message");
}

 

 

여러 메서드 참조 (멀티캐스트 대리자)

대리자는 여러 메서드를 참조할 수 있으며, 이는 += 연산자를 사용하여 추가할 수 있습니다.

del += AnotherMethod;
del("This calls both MethodToCall and AnotherMethod");

 

 

대리자의 확장(Event)

C#에서 이벤트(Event)는 대리자의 확장으로, 특정 사건이 발생할 때 이를 알리는 방법을 제공합니다. 이벤트는 일반적으로 UI 상호작용, 데이터 변경, 상태 변경 등에서 사용됩니다. 이벤트는 발행자(publisher)와 구독자(subscriber) 간의 통신을 가능하게 합니다.

 

 

이벤트의 주요 구성요소

1. 이벤트 발행자:

  • 이벤트가 발생하는 클래스.
  • 이벤트를 선언하고 발생시키는 역할.

 

2. 이벤트 구독자

  • 이벤트를 처리하는 클래스.
  • 이벤트가 발생했을 때 실행될 메서드를 제공.

 

 

이벤트의 선언 및 사용

 

1. 이벤트 선언

public class Publisher
{
    // 대리자를 선언
    public delegate void NotifyEventHandler(object sender, EventArgs e);
    
    // 이벤트 선언
    public event NotifyEventHandler NotifyEvent;
    
    // 이벤트를 발생시키는 메서드
    public void RaiseEvent()
    {
        if (NotifyEvent != null)
        {
            NotifyEvent(this, EventArgs.Empty);
        }
    }
}

 

2. 이벤트 구독 및 처리

public class Subscriber
{
    public void OnNotify(object sender, EventArgs e)
    {
        Console.WriteLine("Event received.");
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        Publisher publisher = new Publisher();
        Subscriber subscriber = new Subscriber();
        
        // 이벤트 구독
        publisher.NotifyEvent += subscriber.OnNotify;
        
        // 이벤트 발생
        publisher.RaiseEvent(); // 출력: Event received.
    }
}

 

 

이벤트와 대리자의 차이점

  • 대리자: 특정 메서드를 참조할 수 있는 객체로, 대리자 인스턴스를 통해 메서드를 호출할 수 있습니다.
  • 이벤트: 대리자를 기반으로 한 확장 개념으로, 특정 사건이 발생할 때 구독자에게 알리는 방식입니다. 이벤트는 주로 'event' 키워드를 사용하여 선언되며, 이벤트를 선언한 클래스 내에서만 호출할 수 있습니다.

 

 

 

 

2. 대리자의 종류(Action, Func, Predicate)

C#에서는 대리자의 사용을 편리하게 하기 위해 'Action', 'Func', 'Predicate'와 같은 내장 대리자 타입을 제공합니다. 이러한 대리자는 일반적인 메서드 시그니처를 쉽게 처리할 수 있도록 도와줍니다. 각 대리자의 사용 시나리오와 코드 예제를 살펴보겠습니다.

 

 

1. Action 대리자

Action 대리자는 반환값이 없는 메서드를 나타내기 위해 사용됩니다. 매개변수의 개수에 따라 다양한 버전이 있으며, 최대 16개까지 매개변수를 가질 수 있습니다.

 

사용 시나리오

  • 이벤트 핸들러
  • 특정 작업을 수행하지만 값을 반환할 필요가 없는경우

 

예제

using System;

public class ActionExample
{
    public static void PrintMessage(string message)
    {
        Console.WriteLine(message);
    }

    public static void Main()
    {
        Action<string> action = PrintMessage;
        action("Hello, Action!"); // 출력: Hello, Action!
    }
}

 

 

 

2. Func 대리자

Func대리자는 값을 반환하는 메서드를 나타내기 위해 사용됩니다. 마지막 타입 매개변수가 반환 타입을 나타내며, 최대 16개까지 매개변수를 가질 수 있습니다.

 

사용 시나리오

  • 계산 결과를 반환해야 하는 경우
  • 데이터 처리를 위한 람다 식

 

예제

using System;

public class FuncExample
{
    public static int Add(int x, int y)
    {
        return x + y;
    }

    public static void Main()
    {
        Func<int, int, int> func = Add;
        int result = func(5, 3); // result는 8
        Console.WriteLine(result); // 출력: 8
    }
}

 

 

 

3. Predicate 대리자

Predicate 대리자는 특정 조건을 검사하여 bool 값을 반환하는 메서드를 나타내기 위해 사용됩니다. 단 하나의 매개변수를 가집니다.

 

사용 시나리오

  • 컬렉션의 요소를 필터링할 때
  • 특정 조건에 맞는지 검사할 때

 

예제

using System;

public class PredicateExample
{
    public static bool IsEven(int number)
    {
        return number % 2 == 0;
    }

    public static void Main()
    {
        Predicate<int> predicate = IsEven;
        bool isEven = predicate(4); // isEven은 true
        Console.WriteLine(isEven); // 출력: True
    }
}

 

 

 

4. 요약

  • Action: 반환값이 없는 메서드에 사용. 예: Action<string> action = PrintMessage;
  • Func: 값을 반환하는 메서드에 사용. 예: Func<int, int, int> func = Add;
  • Predicate: 조건을 검사하여 bool 값을 반환하는 메서드에 사용. 예: Predicate<int> predicate = IsEven;

 

 

 

 


지금까지 C# 대리자에 대해 알아보았습니다.

현재 글의 내용 중 틀린 부분이나, 지적하실 내용이 있으시다면 언제든지 알려주세요! 읽어주셔서 감사합니다.

 

'CS 공부' 카테고리의 다른 글

[C#] 변수 종류와 키워드  (0) 2024.08.09
[C#] 클래스와 구조체 (Class & Structure)  (0) 2024.08.04
[C#] 메모리 구조  (0) 2024.07.22
[C#] 가비지 컬렉터 (Garbage Collector, GC)  (0) 2024.07.15
[C#] Virtual, Abstract, Interface  (0) 2024.07.09