델리게이트 ( Delegate )
프로그래밍을 하다 보면 특정 상황에서 어떤 동작을 나중에 결정해야 하는 경우가 있다.
사용자 인터페이스 ( UI ) 에서 버튼이 클릭됐을 때 특정 동작을 수행하도록 만들고 싶을때
게임에서 몬스터를 처치했을 때 , 코인 적립 , 경험치 지급 등 여러 가지 동작이 동시에 수행되어야 할 때
파일 다운로드 진행 상황을 표시하는 라이브러리에서 다운로드가 진행될 때마다 진행률을 업데이트 할 때
이런 문제를 해결하기 위한 C# 기능 중 하나가 바로 델리게이트 ( Delegate )이다.
해석하면 "대리인" 이라는 뜻의 델리게이트는 "함수를 변수처럼 다룰 수 있는 기능" 이다.
즉 , 함수 자체를 변수에 저장하거나 매개변수로 전달할 수 있게 해주는 기능이다.
게임에서 플레이어가 몬스터를 처치했을 때 어떤 보상을 줄지는 상황에 따라 다를 수 있다.
일반 몬스터 → 경험치 + 골드 보상
보스 몬스터 → 경험치 + 유니크 장비
이 보상 주는 로직을 몬스터 클래스에 고정하면 모든 보상 처리를 몬스터 클래스가 알아야한다.
외부에서 보상과 관련된 함수를 전달해주고 그걸 실행하는 구조로 유연하게 처리할수 있다.
문법
▼델리게이트 선언
delegate 반환형 Delegate이름(매개변수목록);
// 반환형과 매개변수를 정의한 델리게이트 타입 선언
public delegate void RewardDelegate(int exp, int gold);
RewardDelegate 는 void 반환형 , int 2개의 매개변수를 가진 함수를 저장할 수 있는 타입이 된다.
▼델리게이트 객체 생성 및 메서드 연결
Delegate이름 d = new Delegate이름(메서드명);
▼델리게이트 호출
d(인자);
▼1. 예시 코드
using System;
class Program
{
// 1. 델리게이트 선언
delegate void MyDelegate(string msg);
// 2. 메서드 정의
static void PrintHello(string msg) => Console.WriteLine("Hello, " + msg);
static void PrintBye(string msg) => Console.WriteLine("Bye, " + msg);
static void Main()
{
// 3. 델리게이트 인스턴스 생성 및 메서드 연결
MyDelegate del = PrintHello;
del("Ho-chan"); // Hello, Ho-chan
// 4. 다른 메서드로 교체
del = PrintBye;
del("Ho-chan"); // Bye, Ho-chan
// 5. 멀티캐스트 델리게이트
del += PrintHello;
del("Ho-chan"); // Bye, Ho-chan
// Hello, Ho-chan
}
}
▼2. 예시 코드
class Monster
{
public RewardDelegate onDefeated;
public void Defeat()
{
Console.WriteLine("몬스터를 처치했습니다!");
onDefeated?.Invoke(100, 50); // 델리게이트 호출
}
}
class Program
{
static void Main()
{
Monster monster = new Monster();
monster.onDefeated = GiveReward;
monster.Defeat(); // GiveReward 실행됨
}
static void GiveReward(int exp, int gold)
{
Console.WriteLine($"{exp} 경험치와 {gold} 골드를 획득!");
}
}
델리게이트 덕분에 Monster 클래스는 보상 로직을 몰라도 상관없다.
어떻게 보상할지는 외부에서 정하고, 몬스터는 그 함수를 나중에 호출만 하면 된다.
▼델리게이트 체인 ( Multicast Delegate )
하나의 델리게이트에 여러 함수를 연결할 수도 있다.
RewardDelegate reward = GiveReward;
reward += GiveBonus;
reward(100, 50);
+= 를 사용하여 델리게이트에 함수를 추가하면 순차적으로 모두 실행된다
class Program
{
// 1. 델리게이트 선언
delegate void MyDelegate(string msg);
// 2. 메서드 정의
static void PrintHello(string msg) => Console.WriteLine("Hello, " + msg);
static void PrintBye(string msg) => Console.WriteLine("Bye, " + msg);
static void PrintWelcome(string msg) => Console.WriteLine("Welcome, " + msg);
static void Main()
{
// 3. 델리게이트 체인 생성
MyDelegate del = PrintHello;
del += PrintBye;
del += PrintWelcome;
// 4. 실행 → 연결된 메서드들이 순서대로 호출됨
del("Ho-chan");
// 5. 체인에서 제거
del -= PrintBye;
Console.WriteLine("\n체인에서 PrintBye 제거 후:");
del("Ho-chan");
}
}
▼출력
Hello, Ho-chan
Bye, Ho-chan
Welcome, Ho-chan
체인에서 PrintBye 제거 후:
Hello, Ho-chan
Welcome, Ho-chan
핵심 포인트
- += : 델리게이트에 메서드를 체인 방식으로 추가
- -= : 체인에서 특정 메서드 제거 가능
- 호출 시 연결된 모든 메서드가 순차적으로 실행된다
- 단, 리턴값이 있는 델리게이트의 경우 마지막 메서드의 반환값만 유지된다.
익명 함수 ( Anonymous Method )
익명 함수는 이름이 없는 메서드를 delegate 키워드로 직접 정의해서 델리게이트레 할당하는 방식이다.
▼예시 코드
class Program
{
delegate void MyDelegate(string msg);
static void Main()
{
// 익명 함수 사용
MyDelegate del = delegate (string text)
{
Console.WriteLine("익명 함수 호출: " + text);
};
del("Ho-chan"); // 실행 결과: 익명 함수 호출: Ho-chan
}
}
delegate ( 매개변수 ) { 실행문; }
코드가 간결해지고, 단 한 번만 쓰일 함수에 적합하다.
람다식 ( Lambda Expression )
람다식은 익명 함수를 더 간결하게 표현하는 문법이다.
화살표 ( => ) 를 사용하여 작성한다.
▼예시 코드
class Program
{
delegate void MyDelegate(string msg);
static void Main()
{
// 람다식 사용
MyDelegate del = (text) => Console.WriteLine("람다식 호출: " + text);
del("Ho-chan"); // 실행 결과: 람다식 호출: Ho-chan
}
}
( 매개변수 ) => 실행식
표현식 본문 ( 한줄 ) - 중괄호 생략 가능하다
여러 줄일 경우 { } 사용
한줄 요약
익명 함수 : delegate 키워드로 만든 이름 없는 함수
람다식 : 화살표 ( => ) 를 사용한 더 간결한 익명 함수 문법
사용하면 좋은 상황
- 이벤트 처리기 ( Event Handler ) 작성할 때 ( 버튼 클릭 , 키 입력 등 )
- 콜백 메서드를 전달할 때 ( 비동기 작업 , 정렬 기준 함수 등 )
- 런타임에 동적으로 실행할 메서드를 선택해야 할 때
- 코드의 유연성과 재사용성을 높이고 싶을 때
주의할 점
- 잘못된 메서드를 연결하면 런타임 에러 발생 가능
- 멀티캐스트 델리게이트 사용 시 호출 순서가 보장되지 않는다
- null 상태에서 호출하면 예외 ( NullReferenceException ) 발생 - 호출 전 null 체크 필수
- 델리게잍느 남용 시 코드 가독성 저하 및 디버깅이 어렵다
정리
델리게이트는 메서드를 변수처럼 다룰 수 있게 해주는 타입 안전한 함수 포인터이다
이벤트와 콜백을 구현할 때 유용하다.
참고 자료
https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/delegates/using-delegates
'⭐C Sharp > 12. 델리게이트' 카테고리의 다른 글
| 캡처와 클로저 ( Capture & Closure ) (0) | 2025.11.15 |
|---|---|
| invoke (0) | 2025.10.09 |