익명 델리게이트(anonymous delegate)

황현중·2025년 11월 27일

C#

목록 보기
12/24

1. 델리게이트 개념 복습

익명 델리게이트를 이해하려면, “델리게이트 = 메서드를 가리키는 변수 타입”이라는 개념을 먼저 짚고 가야 한다.

delegate bool NumberTest(int n); 
// int 하나 받아서 bool(true/false)을 반환하는 메서드를 가리킬 수 있는 타입

이제 이 델리게이트 타입을 이용해 이런 식으로 쓸 수 있다.

static bool IsEven(int n)   { return n % 2 == 0; }
static bool IsOdd(int n)    { return n % 2 != 0; }

static int Count(int[] numbers, NumberTest test)
{
    int count = 0;
    foreach (int n in numbers)
    {
        if (test(n))  // test가 가리키는 메서드를 호출
            count++;
    }
    return count;
}

int[] arr = { 3, 5, 4, 2, 6, 7, 8 };

int evenCount = Count(arr, IsEven);
int oddCount  = Count(arr, IsOdd);

여기까지는 “이름 있는 메서드(IsEven, IsOdd)를 델리게이트에 넘겨서 쓰는 패턴”이다.


2. 익명 델리게이트란?

익명 델리게이트(anonymous delegate)는 말 그대로 “이름 없는 메서드”를 즉석에서 만들어서 델리게이트 자리에 넣는 문법이다.

방금 예제를 익명 델리게이트로 바꾸면 이렇게 쓸 수 있다.

int[] arr = { 3, 5, 4, 2, 6, 7, 8 };

// 짝수 개수
int evenCount = Count(
    arr,
    delegate(int n)
    {
        return n % 2 == 0;
    }
);

// 홀수 개수
int oddCount = Count(
    arr,
    delegate(int n)
    {
        return n % 2 != 0;
    }
);

여기서 포인트는 이 부분이다:

delegate(int n)
{
    return n % 2 == 0;
}
  • delegate(int n) { ... } → 이름이 없는 메서드(익명 메서드)
  • 이 익명 메서드가 NumberTest 타입 델리게이트로 들어감
  • 결국 IsEven, IsOdd 같은 별도 메서드를 안 만들고, 그 자리에서 조건을 바로 적어버리는 것

즉, “이름 없는 메서드를 즉석에서 만들어서 델리게이트로 넘기는 것”이 익명 델리게이트다.


3. 왜 익명 델리게이트를 쓰는가?

주요 이유는 크게 세 가지 정도로 정리할 수 있다.

  1. 한 번만 쓸 간단한 함수를 위해 이름을 만들기 귀찮을 때
  2. 해당 위치에서 바로 로직이 보였으면 좋을 때 (가독성)
  3. 이벤트/콜백처럼 짧은 동작을 등록할 때

예를 들어, 아래처럼 쓸 수도 있다.

// 이름 있는 함수 버전
static bool GreaterThanTen(int n)
{
    return n > 10;
}

int count = Count(arr, GreaterThanTen);

// 익명 델리게이트 버전
int count2 = Count(
    arr,
    delegate(int n)
    {
        return n > 10;
    }
);

동일한 동작을 하지만, “딱 여기에서 한 번만 쓸 조건”이라면 익명 델리게이트를 쓰는 편이 코드가 더 모여 있고 보기 좋을 수 있다.


4. 예제 전체 코드: Count + 익명 델리게이트

아래는 간단한 콘솔 프로그램 전체 코드다.

using System;

delegate bool NumberTest(int n);  // 조건을 표현하는 델리게이트 타입

class Program
{
    static void Main()
    {
        int[] arr = { 3, 5, 4, 2, 6, 7, 8, 11, 13, 15, 20 };

        // 1) 짝수 개수 - 익명 델리게이트 사용
        int evenCount = Count(
            arr,
            delegate(int n)
            {
                return n % 2 == 0;
            }
        );

        // 2) 홀수 개수
        int oddCount = Count(
            arr,
            delegate(int n)
            {
                return n % 2 != 0;
            }
        );

        // 3) 10보다 큰 수 개수
        int greaterThanTenCount = Count(
            arr,
            delegate(int n)
            {
                return n > 10;
            }
        );

        Console.WriteLine("짝수 개수: " + evenCount);
        Console.WriteLine("홀수 개수: " + oddCount);
        Console.WriteLine("10보다 큰 수 개수: " + greaterThanTenCount);

        Console.ReadKey();
    }

    // 공통 Count 함수: 조건을 델리게이트로 받음
    static int Count(int[] numbers, NumberTest test)
    {
        int count = 0;
        foreach (int n in numbers)
        {
            if (test(n))   // 여기서 test가 가리키는 익명 메서드가 실제로 호출됨
                count++;
        }
        return count;
    }
}

이 코드를 실행해보면,
IsEven, IsOdd 같은 별도 메서드 정의 없이도 조건을 그 자리에서 바로 적어서 Count 할 수 있다는 점이 보인다.


5. 이벤트에서의 익명 델리게이트

익명 델리게이트는 특히 이벤트 핸들러에서 많이 쓰였다 (C# 2.0 시대 코드들에서 자주 볼 수 있는 패턴).

5-1. 일반적인 이벤트 핸들러 방식

button1.Click += Button1_Click;

void Button1_Click(object sender, EventArgs e)
{
    MessageBox.Show("버튼 클릭!");
}

5-2. 익명 델리게이트를 사용한 방식

button1.Click += delegate(object sender, EventArgs e)
{
    MessageBox.Show("버튼 클릭!");
};

차이점은,

  • 위쪽은 Button1_Click이라는 메서드를 따로 만들어서 연결
  • 아래쪽은 이벤트 연결하는 자리에서 바로 익명 메서드를 작성

실제 동작은 완전히 동일하다. 다만 한 번만 쓸 간단한 핸들러라면, 익명 델리게이트를 쓰는 쪽이 코드를 더 모아두는 효과가 있다.


6. 익명 델리게이트와 람다식의 관계

요즘 C# 코드를 보면, 익명 델리게이트보다는 람다식(lambda)을 훨씬 많이 쓴다. 사실 람다식은 익명 델리게이트의 “짧은 문법 버전”이라고 보면 된다.

6-1. 익명 델리게이트 버전

int evenCount = Count(
    arr,
    delegate(int n)
    {
        return n % 2 == 0;
    }
);

6-2. 같은 코드의 람다식 버전

int evenCount = Count(
    arr,
    n => n % 2 == 0
);
  • delegate(int n) { return n % 2 == 0; } → 매개변수 타입+본문을 풀로 쓴 형태
  • n => n % 2 == 0 → 같은 의미를 가진 더 짧은 표현(람다식)

결국 내부에서는 둘 다 NumberTest 델리게이트로 취급된다. 문법만 간단해졌을 뿐, “함수를 값처럼 넘긴다”라는 근본 개념은 똑같다.


0개의 댓글