반응형
해당 포스팅은 개인적으로 C# WPF를 공부하면서 익힌 내용을 기억에 남기기 위한 작업의 일환으로 작성된 글로서
일부 내용에 오류가 있을 수도 있으니 참고하시기 바랍니다.

 

 

 

C#WPF 프로그래밍에서 많이 사용되는
delegate의 개념과 사용 방법에 대해 살펴보고
event와의 차이점은 
무엇인지 알아보자.

 

반응형
내용 요약

C#에서 delegate는 메서드에 대한 참조를 나타내는 형식으로,

메서드를 변수처럼 다룰 수 있게 해준다.

delegate는 콜백 메서드나 이벤트 처리기 등을 구현할 때 유용하게 사용되는데,

이 글에서는 delegate의 정의, 선언, 사용 방식에 대해 자세히 설명하고,

다양한 예제와 함께 delegate의 활용 방법을 다룹니다.

(delegate에 대해 작성하다보니 내용이 너무 많아져서,

event에 대한 내용은 다음 포스팅에서 다루도록 하겠습니다.)

 

 

1.개념 정의(delegate)

 

   1. delegate의 정의

delegate는 특정 메서드 시그니처를 가지는 형식을 정의한다.

예를 들어, 반환형이 void이고 매개변수가 두 개(int형과 string형)인 메서드를 참조하는 

delegate를 정의하려면 다음과 같이 작성한다.

public delegate void MyDelegate(int number, string text);

 

이 정의는 MyDelegate라는 이름의 delegate 형식을 생성한다.

이 delegate는 반환형이 void이고 매개변수가 int와 string인 메서드를 참조할 수 있다.

 

   2. delegate의 선언

delegate를 정의한 후, 이를 변수처럼 선언할 수 있다.

예를 들어, MyDelegate를 사용하여 변수를 선언하고 특정 메서드를 할당할 수 있다.

MyDelegate del;

 

이제 del 변수는 MyDelegate 형식의 delegate를 참조할 수 있으며

이 변수에 메서드를 할당하고 호출할 수 있다.

 

   3. delegate의 사용

delegate를 사용하려면, 먼저 해당 시그니처와 일치하는 메서드를 정의하고,

이를 delegate 변수에 할당한 후 호출할 수 있다.
다음은 delegate를 정의하고 사용하는 예제이다.

using System;

public class Program
{
    // Delegate 정의
    public delegate void MyDelegate(int number, string text);

    // Delegate와 일치하는 메서드 정의
    public static void MyMethod(int number, string text)
    {
        Console.WriteLine($"Number: {number}, Text: {text}");
    }

    public static void Main()
    {
        // Delegate 변수 선언 및 메서드 할당
        MyDelegate del = new MyDelegate(MyMethod);

        // Delegate를 사용하여 메서드 호출
        del(42, "Hello, World!");

        // 또는
        del.Invoke(42, "Hello, World!");
    }
}

 

위 예제에서 MyDelegate는 int와 string을 매개변수로 받고 

void를 반환하는 메서드를 참조할 수 있는 delegate이다. 

MyMethod는 이 시그니처와 일치하는 메서드로, 

del이라는 delegate 변수에 할당되어 호출된다.

 

   4. delegate chain

delegate는 여러 메서드를 참조할 수 있는 멀티캐스트 기능도 제공한다. 

+= 연산자를 사용하여 여러 메서드를 delegate에 추가할 수 있다

del은 MyMethod와 AnotherMethod를 모두 참조하며, 호출 시 두 메서드가 순차적으로 실행된다.

멀티캐스트 delegate는 여러 메서드를 한 번에 호출할 수 있는 강력한 기능을 제공한다.

public static void AnotherMethod(int number, string text)
{
    Console.WriteLine($"Another Method - Number: {number}, Text: {text}");
}

public static void Main()
{
    MyDelegate del = new MyDelegate(MyMethod);
    del += AnotherMethod;

    // Delegate를 사용하여 두 메서드 모두 호출
    del(42, "Hello, World!");
}

 

   5. delegate의 반환값 처리 (multicast의 경우)

delegate를 멀티캐스트로 사용하는 경우,

마지막으로 호출된 메서드의 반환값만을 반환한다.

예를 들어, 다음과 같은 delegate를 정의하고 사용해보자.

public delegate int MyReturnDelegate(int number);

public static int Method1(int number)
{
    Console.WriteLine($"Method1: {number}");
    return number + 1;
}

public static int Method2(int number)
{
    Console.WriteLine($"Method2: {number}");
    return number + 2;
}

public static void Main()
{
    MyReturnDelegate del = new MyReturnDelegate(Method1);
    del += Method2;

    int result = del(10);
    Console.WriteLine($"Result: {result}");
}

 

del은 Method1과 Method2를 모두 참조한다. del(10)을 호출하면 두 메서드가 순차적으로 실행되며,

마지막 메서드인 Method2의 반환값이 result에 저장되며 출력은 다음과 같다.

Method1: 10
Method2: 11
Result: 12

 

   6.delegate의 유용성

 

delegate는 다양한 시나리오에서 유용하게 사용될 수 있다.
첫번째, 콜백 메서드
콜백 메서드는 특정 작업이 완료된 후 호출되는 메서드이다.

delegate를 사용하여 콜백 메서드를 구현할 수 있다.

예를 들어, 파일을 비동기적으로 읽고 완료되면 콜백 메서드를 호출하는 코드를 작성해보면,

using System;
using System.IO;
using System.Threading.Tasks;

public class Program
{
    public delegate void FileReadCallback(string content);

    public static async Task ReadFileAsync(string filePath, FileReadCallback callback)
    {
        string content = await File.ReadAllTextAsync(filePath);
        callback(content);
    }

    public static void OnFileRead(string content)
    {
        Console.WriteLine("File content:");
        Console.WriteLine(content);
    }

    public static async Task Main()
    {
        string filePath = "example.txt";
        await ReadFileAsync(filePath, OnFileRead);
    }
}

 

위 예제에서 FileReadCallback은 파일 읽기가 완료된 후

호출될 콜백 메서드를 정의하는 delegate이다. 

ReadFileAsync 메서드는 파일을 비동기적으로 읽고, 완료되면 callback을 호출한다.

OnFileRead 메서드는 콜백 메서드로, 파일 내용을 출력한다.

 

두번째, 이벤트 처리기
이벤트는 특정 작업이 발생했을 때 실행되는 메서드이다.

C#에서는 delegate를 사용하여 이벤트를 처리할 수 있는데

using System;

public class Button
{
    public delegate void ClickEventHandler(object sender, EventArgs e);
    public event ClickEventHandler Click;

    public void OnClick()
    {
        if (Click != null)
        {
            Click(this, EventArgs.Empty);
        }
    }
}

public class Program
{
    public static void Button_Click(object sender, EventArgs e)
    {
        Console.WriteLine("Button clicked!");
    }

    public static void Main()
    {
        Button button = new Button();
        button.Click += Button_Click;

        button.OnClick();
    }
}

 

위 예제에서 ClickEventHandler는 버튼 클릭 이벤트를 처리하는 delegate이다. 

Button 클래스는 Click 이벤트를 정의하고, OnClick 메서드를 통해 이벤트를 발생시킨다.

Button_Click 메서드는 이벤트 처리기로, 버튼이 클릭되었을 때 호출된다.

 

   7.delegate와 람다식

C#에서는 람다식을 사용하여 delegate를 간편하게 정의할 수 있다.

람다식은 익명 메서드를 간결하게 표현하는 방법으로서

아래 예제는 람다식을 사용하여 delegate를 정의하고 사용하는 예제이다.

using System;

public class Program
{
    public delegate int MyDelegate(int x, int y);

    public static void Main()
    {
        MyDelegate add = (x, y) => x + y;
        MyDelegate multiply = (x, y) => x * y;

        Console.WriteLine($"Add: {add(3, 4)}");
        Console.WriteLine($"Multiply: {multiply(3, 4)}");
    }
}

 

위 예제에서 add와 multiply는 각각 두 정수를 더하고 곱하는 람다식을 사용하여 정의된 delegate이다.

람다식을 사용하면 delegate를 간결하게 정의하고 사용할 수 있다.

반응형

+ Recent posts