본문 바로가기
Language/C#

[C# Basic] Delegate 개념부터 활용까지

by 잘 까먹는 다람쥐 2025. 2. 10.

source : Delegates in C# Help in Writing Maintain, Reusable, and Test

C# 에서는 Delegate 문법이 존재한다.

 

delegate 는 한국어로 "위임하다" 라는 뜻을 가진다.

 

도대체 어떤 것을 위임한다는 걸까?

 

오늘은 Delegate에 대해서 깊이 파헤쳐보자.


목차

  1. Delegate란?
  2. Delegate는 어떻게 동작하는가?
  3. Delegate의 기본 사용법
  4. Delegate 활용 예제
  5. Delegate와 이벤트의 관계
  6. Action과 Func
  7. Delegate를 사용하는 이유

1. Delegate란?

C#에서 delegate특정 메서드를 참조할 수 있는 타입이다. 쉽게 말해, 메서드에 대한 포인터 역할을 하며, 특정 메서드를 변수처럼 저장하고 실행할 수 있게 해준다. C/C++의 함수 포인터와 유사하지만, 타입 안전성을 보장하여 더 안전하게 사용할 수 있다.


2. Delegate는 어떻게 동작하는가?

Delegate는 메서드의 참조를 저장하고 있다가 필요할 때 해당 메서드를 호출하는 방식으로 동작한다.

Delegate를 활용하면 런타임에 실행할 메서드를 동적으로 변경할 수 있다.


3. Delegate의 기본 사용법

3.1 Delegate 선언 및 사용

using System;

// Delegate 선언
public delegate void MyDelegate(string message);

class Program
{
    // Delegate가 참조할 메서드 정의
    static void PrintMessage(string msg)
    {
        Console.WriteLine($"메시지: {msg}");
    }

    static void Main()
    {
        // Delegate 인스턴스 생성 및 메서드 연결
        MyDelegate del = new MyDelegate(PrintMessage);
        
        // Delegate 호출
        del("Hello, Delegate!");
    }
}

3.2 멀티캐스트 Delegate

Delegate는 여러 개의 메서드를 하나로 묶어 한 번에 실행할 수 있다.

using System;

public delegate void MultiDelegate();

class Program
{
    static void Method1() => Console.WriteLine("Method1 실행");
    static void Method2() => Console.WriteLine("Method2 실행");

    static void Main()
    {
        MultiDelegate del = Method1;
        del += Method2; // Method2 추가
        
        del(); // Method1과 Method2가 모두 실행됨
    }
}

4. Delegate의 활용 예제

Delegate는 다양한 용도로 활용된다. 대표적인 예로 이벤트(Event) 시스템이 있다.

using System;

// Delegate 선언
public delegate void Notify();

class EventPublisher
{
    public event Notify OnProcessCompleted; // 이벤트 선언

    public void Process()
    {
        Console.WriteLine("작업 수행 중...");
        System.Threading.Thread.Sleep(2000);
        
        OnProcessCompleted?.Invoke(); // 이벤트 발생
    }
}

class Program
{
    static void Main()
    {
        EventPublisher obj = new EventPublisher();
        obj.OnProcessCompleted += () => Console.WriteLine("작업 완료!");
        
        obj.Process();
    }
}

5. Delegate와 이벤트의 관계

C#의 이벤트는 Delegate를 기반으로 동작한다.

이벤트는 특정 동작이 발생했을 때 이를 구독한 메서드를 자동으로 실행하는 방식이다.


6. Action과 Func

C#에서는 delegate를 간편하게 사용하기 위해 Action<>Func<> 제네릭 delegate를 제공한다.

6.1 Action

Action<>은 반환값이 없는 delegate를 나타낸다. 최대 16개의 매개변수를 받을 수 있다.

using System;

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

    static void Main()
    {
        Action<string> action = PrintMessage;
        action("Hello, Action!");
    }
}

6.2 Func

Func<>는 반환값이 있는 delegate를 나타낸다. 마지막 제네릭 매개변수가 반환 타입이 된다.

using System;

class Program
{
    static int Add(int a, int b)
    {
        return a + b;
    }

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

6.3 람다 표현식과 함께 사용

Action<>Func<>는 람다 표현식과 함께 사용하면 더욱 간결한 코드 작성을 가능하게 한다.

class Program
{
    static void Main()
    {
        Action<string> action = msg => Console.WriteLine(msg);
        action("Hello, Lambda Action!");

        Func<int, int, int> func = (x, y) => x + y;
        Console.WriteLine(func(10, 20)); // 출력: 30
    }
}

 

이러한 기능을 활용하면 코드의 가독성과 유지보수성이 향상되며, 불필요한 delegate 선언을 줄일 수 있다. 


7. Delegate를 사용하는 이유

  • 메서드 실행을 동적으로 변경할 수 있음
  • 코드의 재사용성과 유지보수성을 향상
  • 이벤트 기반 프로그래밍을 쉽게 구현
  • 비동기 처리 및 콜백 패턴 구현 가능