Q.delegate(델리게이트)가 뭐야?

A. 메서드(함수)에 대한 참조(주소값,포인터)를 캡슐화 하는 형식(타입)이다.

즉, 메서드를 가리키는 포인터(C,C++의 포인터 아님) , C++의 함수포인터라고 생각하면 쉽다.

Type-Safe(타입-안전)이며 , 객체 지향적으로 설계되있는것이 특징이다.

 

Q.delegate(델리게이트)를 왜 쓰는건데?

A.

1.유연성 : 메서드(함수)를 변수처럼 다룰 수 있다. 런타임 중 메서드를 선택 또는 변경 할수 있음
2.콜백 함수 : 비동기 작업이나 이벤트 처리 시 , 특정 시점에 실행할 메서드를 델리게이트로 전달 가능
3.함수형 프로그래밍 지원 : 람다 표현식과 함께 사용시 간결하고 효율적인 코드 작성 가능

Q.delegate(델리게이트)를 어떡해 쓰는데?

A.

예시 1)

public class Program
{
	// 반환 타입이 void이고, 매개변수가 없는 델리게이트
	public delegate void SimpleDelegate();

	// 반환 타입이 int이고, 두 개의 int 매개변수를 받는 델리게이트
	public delegate int OperationDelegate(int a, int b);

    // 델리게이트 메서드
    public static void SayHello()
    {
        Console.WriteLine("Hello!");
    }

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

    public static void Main()
    {
        // SimpleDelegate 델리게이트 인스턴스 생성 및 메서드 할당
        SimpleDelegate simpleDel = new SimpleDelegate(SayHello);
        simpleDel(); // 출력: Hello!

        // OperationDelegate 델리게이트 인스턴스 생성 및 메서드 할당
        OperationDelegate opDel = new OperationDelegate(Add);
        int result = opDel(5, 3);
        Console.WriteLine(result); // 출력: 8
    }
}

 

예시2)

//델리게이트 안에 여러개의 메서드를 추가 할 수 있다.

public class Program
{
    public delegate void Notify(string message);

    public static void MethodA(string msg)
    {
        Console.WriteLine($"MethodA: {msg}");
    }

    public static void MethodB(string msg)
    {
        Console.WriteLine($"MethodB: {msg}");
    }

    public static void Main()
    {
        Notify notifyDel = MethodA;
        notifyDel += MethodB; // 델리게이트 체인에 MethodB 추가
        //+= 연산자로 메서드를 추가할수 있다.

        notifyDel("Hello Delegates!");
        // 출력:
        // MethodA: Hello Delegates!
        // MethodB: Hello Delegates!
    }
}

예시2) 의 사용은 += 연산자로 델리게이트 변수에 메서드를 추가하고 있으며,
주로 반환타입이 void인 델리게이트에서 사용된다. 
반환값이 있는 경우 체인에 연결된 마지막 메서드 반환값만 반환

 

Q.delegate(델리게이트)와 event(이벤트)와 관계가 있다는 무슨관계야?

A. 이벤트는 델리게이트를 기반으로 구현 된 함수포인터라고 생각하면된다.

하지만 event를 선언한 클래스 내부에서만 저장한 메서드들을 동작 시킬수 있다.

public class Publisher
{
    // 이벤트 선언
    public event Action OnChange;

    public void RaiseEvent()
    {
    	//이벤트 변수를 선언한 클래스 내부에서 Invoke()로 동작시키는 모습
        //변수 뒤에 ?는 해당 이벤트가 null 이면 동작을 막는 예외처리 키워드이다.
        OnChange?.Invoke();
    }
}

public class Subscriber
{
    public void Subscribe(Publisher publisher)
    {
    	//이벤트 변수에 메서드를 추가하고 있다.
        //이벤트는 외부에서도 추가/삭제가 가능하다.
        publisher.OnChange += Respond;
    }

    private void Respond()
    {
        Console.WriteLine("Event received and handled.");
    }
}

public class Program
{
    public static void Main()
    {
        Publisher publisher = new Publisher(); //이벤트 변수가 있는 클래스
        Subscriber subscriber = new Subscriber(); //이벤트 변수에 메서드를 추가하는 클래스

        subscriber.Subscribe(publisher);
        publisher.RaiseEvent(); // 출력: Event received and handled.
    }
}

subscriber 클래스를 보면 이벤트가 들어있는 변수(publisher)를 인자값으로 가져간 뒤 event에 메서드를 저장 한다.

그 이후 publisher에서 invoke()로 함수 동작시 subscriber의 함수가 동작하게 된다.

 

이렇게 외부 클래스의 함수를 특정 시점에 원할때 쓸 수있는것이 event 함수이다.

이 패턴은 옵저버 패턴과 매우 유사하다.

 

Q.C#에서 델리게이트 기반으로 된 함수포인터 변수는 event가 끝인거야?

A.물론 아니다.

보통 6개의 델리게이트를 많이 사용하게 될 것이다.

 

1. Delegate 기본 타입 : 모든 델리게이트의 기본 클래스.

2. Event 델리게이트 : 이벤트 처리에 사용되는 델리게이트.

3. Action 델리게이트 : 반환값이 없는 메서드를 참조.

Action action = () => Console.WriteLine("Hello");
action(); // 출력: Hello

Action<int> printNumber = (number) => Console.WriteLine(number);
printNumber(10); // 출력: 10


4. Func 델리게이트 : 반환값이 있는 메서드를 참조.

Func<int, int, int> add = (a, b) => a + b;
Console.WriteLine(add(3, 4)); // 출력: 7


5. Predicate 델리게이트 : bool 값을 반환하는 조건 검사를 위한 메서드 참조.

Predicate<int> isEven = (x) => x % 2 == 0;
Console.WriteLine(isEven(4)); // 출력: True
Console.WriteLine(isEven(3)); // 출력: False

이 델리게이트는 List 컨테이너의 Find 함수에 인자값으로 안내가 되어있다.


6. Comparison 델리게이트 : 두 객체를 비교하는 메서드 참조.

Comparison<int> comparison = (a, b) => a.CompareTo(b);
int[] numbers = { 3, 1, 4, 1, 5 };
Array.Sort(numbers, comparison);

주로 정렬에 사용된다.

 


오늘 TextRPG 팀프로젝트를 하고 발표를 하는 중 delegate를 사용한 팀이 있어서

생각해보니 정확한 개념을 모르는 것 같아 다시 한번 정리해 보았다.

+ Recent posts