C#/프로그래밍 고급

C# 프로그래밍 고급 - 06. 델리게이터

tita 2024. 5. 30. 16:03

델리게이터(Delegate)는 대리자라고도 하며 메서드를 찹조하는 타입입니다.

함수 포인터나 콜백과 동일한 동작으로 delegate를 호출하면 참조하고 있는 메서드가 호출됩니다.

참조하는 함수의 반환 형식 및 매개변수를 사용하여 선언합니다.

public delegate [반환형식] [이름] (매개변수)

 

델리게이터는 클래스와 같은 자료형으로 다음과 같은 방법으로 사용합니다. 그리고 이것을 변수로 만들어 초기화할 떄 사용하는 것이 메서드 이름, 무명 델리게이터, 람다입니다. 용어와 사용 위치를 확실하게 구분해야 합니다.

 

우선 델리게이터의 선언과 초기화하는 코드를 살펴보겠습니다.

// 클래스 외부에 선언할 수 있습니다.
// public delegate void TestDelegateA();


class Program
{
    //클래스 내부에 선언할 수 있습니다.
    public delegate void TestDelegate();
    
    static void Main(string[] args)
    {
        // 새로 선언한 델리게이터 자료형으로 변수를 선언합니다.
        TestDelegate delegateTest;
        
        
        TestDelegate delegateA = TestMethod; // 메서드 이름을 사용한 초기화 방법
        TestDelegate delegateB = delegate() { }; // 무명 델리게이터를 사용한 초기화 방법
        TestDelegate delegateC = () => { }; // 람다를 사용한 초기화 방법
        
        // 델리게이터는 일반 메서드처럼 호출할 수 있습니다.
        delegateA();
        delegateB();
        delegateC();
    }
    
    static void TestMethod(){    }
}

 

델리게이터를 사용하는 간단한 예제를 살펴보겠습니다.

using System;

// 델리게이터 선언
public delegate void MyDelegate(string message);

class Program
{
    static void Main()
    {
        // 델리게이터 인스턴스화
        MyDelegate del = new MyDelegate(SayHello);
        
        // 델리게이터 호출
        del("Hello, World!");
    }

    static void SayHello(string message)
    {
        Console.WriteLine(message);
    }
}

 

또한 델리게이트는 여러개의 함수를 등록하오 호출할 수 있는 델리게이트 체인(Delegate Chain)을 지원한다.

using System;

public delegate void MyDelegate(string message);

class Program
{
    static void Main()
    {
        MyDelegate del = SayHello;
        
        // 델리게이터에 메서드를 추가
        del += SayGoodbye;
        del("Hello, World!");

        // 델리게이터에 메서드를 제거
        del -= SayHello;
        del("Goodbye, World!");
    }

    static void SayHello(string message)
    {
        Console.WriteLine("Hello: " + message);
    }

    static void SayGoodbye(string message)
    {
        Console.WriteLine("Goodbye: " + message);
    }
}

/*
[실행 결과]
Hello: Hello, World!
Goodbye: Hello, World!
Goodbye: Goodbye, World!
*/

 

1. del("Hello, World!");가 호출될 때 del 델리게이터에는 SayHello와 SayGoodbye가 멀티캐스트로 등록되어 있습니다. 따라서 두 메서드가 순차적으로 호출됩니다.

  • 'sayHello("Hello, World!")' 가 호출되어 "Hello: Hello, World!" 를 출력합니다.
  • 'sayGoodbye("Hello, World!") 가 호출되어 "Goodbye: Hello, World!" 를 출력합니다.

2. del -= SayHello;는 델리게이터에서 SayHello 메서드를 제거합니다. 이제 del 델리게이터에는 SayGoodbye 메서드만 남아 있습니다.

 

 

3. del("Goodbye, World!");가 호출될 때는 del 델리게이터에 SayGoodbye만 남아 있으므로, SayGoodbye("Goodbye, World!")가 호출되어 "Goodbye: Goodbye, World!"를 출력합니다.

 

 

 

 

[무명 델리게이터]

무명 델리게이터는 특정 형식의 델리게이터를 지정하지 않고 사용하는 것을 의미하며, 익명 메서드와 람다 식은 이를 구현하는 두 가지 방법입니다.

익명 메서드는 delegate 키워드를 사용하고, 람다 식은 => 연산자를 사용하여 더 간결하게 표현됩니다.

 

무명 델리게이터는 다음과 같은 형태로 생성합니다.

delegate(<매개변수>, <매개변수>) 
{
    /* 코드 */
    return /* 반환 */ ;
}

 

 

 

<익명 메서드> // Anonymous Method

익명 메서드는 이름이 없는 메서드입니다. 익명 메서드는 델리게이터를 초기화할 때 사용하는 구문 중 하나입니다. 익명 메서드는 delegate 키워드를 사용하여 정의됩니다.

using System;

// 'MyDelegate' 라는 델리게이터 타입을 선언합니다. 
// 하나의 string 매개변수를 받고 반환 값이 없는 메서드를 참조할 수 있습니다.
public delegate void MyDelegate(string message);

class Program
{
    static void Main()
    {
        // MyDelegate 타입의 델리게이터 del 을 선언하고 익명 메서드를 사용하여 초기화합니다.
        MyDelegate del = delegate(string message)
        {
            Console.WriteLine("Anonymous method: " + message);
        };

        del("Hello, World!");
    }
}

/*
[실행 결과]
Anonymous method: Hello, World!
*/

 

 

 

<람다 식> // Lambda Expression

람다 식도 익명 메서드와 비슷하게 델리게이터를 초기화할 때 사용하는 또 다른 방법입니다. 람다 식은 더 간결하게 익명 메서드를 표현할 수 있습니다.

using System;

public delegate void MyDelegate(string message);

class Program
{
    static void Main()
    {
        MyDelegate del = (message) => 
        {
            Console.WriteLine("Lambda expression: " + message);
        };

        del("Hello, World!");
    }
}

/*
[실행 결과]
Lambda expression: Hello, World!
*/

 

이 코드는 람다 식을 사용하여 'MyDelegate' 델리게이터를 초기화힙니다.