
1. delegate 개요
처음 C# delegate를 접했을 때 왜 사용해야 하는지 이해하기가 힘들었습니다.
그래서 왜 사용해야 하는지에 대해 자세히 설명하겠습니다.
C#에는 대리자(delegate)라는 개념이 존재합니다.
대리자라는 용어가 생소할 수도 있는데, 대리기사처럼 대신 일을 해주는 대상이라고 보면 됩니다.
대리자는 한번의 이벤트에 여러 메소드를 동시에 호출할 수 있습니다.
대리자는 메서드를 매개변수로 전달할 수 있습니다.
...
라고 정의하지만 이해가 바로 가지는 않을 겁니다.
소스 코드 예제를 통해 자세히 알아보도록 하고, Delegate의 선언하는 구조만 먼저 집고 넘어가겠습니다.
delegate 반환형 델리게이트명(매개변수, 매개변수, 매개변수, ....);
delegate int ExDelegate(int no, string name);
2. delegate 사용
몬스터를 제거하면 코인을 적립해주는 것을 예시로 들겠습니다.
using System;
namespace ConsoleApplication
{
// delegate 선언
public delegate void PlusDelegate(int score);
public class Program
{
static int userCoin = 0;
// coin 적립 메서드
static void PlusCoin(int score)
{
Console.WriteLine($"UserCoin 적립 : {score}");
userCoin = userCoin + score;
}
static void Main(string[] args)
{
// delegate 초기화/ PlusCoin 메서드 등록
PlusDelegate killDelegate = PlusCoin;
// delegate 호출
killDelegate(100);
// 결과 확인
Console.WriteLine($"UserCoin : {userCoin}");
}
}
}
코드를 이제 하나씩 살펴보겠습니다.
public delegate void PlusDelegate(int score);
int형을 매개변수로 받는 delegate를 생성했습니다.
static int userCoin = 0;
// coin 적립 메서드
static void PlusCoin(int score)
{
Console.WriteLine($"UserCoin 적립 : {score}");
userCoin = userCoin + score;
}
코인점수를 담을 usreCoin변수와, coin을 더해줄 PlusCoin 메서드를 생성했습니다.
// delegate 초기화/ PlusCoin 메서드 등록
PlusDelegate killDelegate = PlusCoin;
// delegate 호출
killDelegate(100);
PlusDelegate를 초기화하고, PlusCoint 메서드를 대리 호출하도록 등록했습니다.
그리고 delegate를 호출합니다.
결과입니다.
요청한 100점이 정상 적립됐네요.

그런데 이상한 점이 있습니다.
delegate를 사용하는 방법은 알겠는데, 왜 굳이 대리자를 호출하면서 사용을 했을까요?
아래 소스처럼 직접 메소드를 호출해도 동일한 결과가 나오는데 말이죠.
using System;
namespace ConsoleApplication
{
public class Program
{
static int userCoin = 0;
// coin 적립 메서드
static void PlusCoin(int score)
{
Console.WriteLine($"UserCoin 적립 : {score}");
userCoin = userCoin + score;
}
static void Main(string[] args)
{
// 메서드 호출
PlusCoin(100);
// 결과 확인
Console.WriteLine($"UserCoin : {userCoin}");
}
}
}
물론 저 상황에서는 delegate를 굳이 쓰지 않아도 되는 것이 맞습니다.
그럼 언제 써야 하는지 이제 살펴보겠습니다.
3. delegate 활용(다중 메서드 호출)
delegate의 장점 중 하나는 하나의 이벤트가 발생했을 때 여러개의 메서드를 동시에 호출할 수 있습니다.
첫번 째 예제에서 몬스터를 죽이면 coin을 적립해줬습니다.
하지만 이제 coin 뿐만이 아니라, point와 경험지(exp)도 적립해줘야 한다면 어떻게 될까요?
이번에는 delegate를 사용하지 않은 소스부터 살펴보겠습니다.
using System;
namespace ConsoleApplication
{
public class Program
{
static int userCoin = 0;
static int userPoint = 0;
static int userExp = 0;
// coin 적립 메서드
static void PlusCoin(int coin)
{
Console.WriteLine($"UserCoin 적립 : {coin}");
userCoin = userCoin + coin;
}
// point 적립 메서드
static void PlusPoint(int point)
{
Console.WriteLine($"UserPoint 적립 : {point}");
userPoint = userPoint + point;
}
static void PlusExp(int exp)
{
Console.WriteLine($"UserExp 적립 : {exp}");
userExp = userExp + exp;
}
static void Main(string[] args)
{
// 메서드 호출
PlusCoin(100);
PlusPoint(30);
PlusExp(40);
// 결과 확인
Console.WriteLine($"UserCoin : {userCoin}, UserPoint : {userPoint}, UserExp : {userExp}");
}
}
}
결과입니다.
3개 모두 정상 적립됐습니다.

메서드를 호출하는 부분을 살펴보겠습니다.
// 메서드 호출
PlusCoin(100);
PlusPoint(30);
PlusExp(40);
메서드를 3개 호출해줘야 하죠. 이런 이벤트 호출 되는 부분이 많고, 지금의 3개보다 더 많은 메서드를 호출해야 한다면
소스코드는 복잡해지게 됩니다.
이제 delegate를 사용해볼까요?
using System;
namespace ConsoleApplication
{
public delegate void PlusDelegate(int coin, int point, int exp);
public class Program
{
static int userCoin = 0;
static int userPoint = 0;
static int userExp = 0;
// coin 적립 메서드
static void PlusCoin(int coin, int point, int exp)
{
Console.WriteLine($"UserCoin 적립 : {coin}");
userCoin = userCoin + coin;
}
// point 적립 메서드
static void PlusPoint(int coin, int point, int exp)
{
Console.WriteLine($"UserPoint 적립 : {point}");
userPoint = userPoint + point;
}
static void PlusExp(int coin, int point, int exp)
{
Console.WriteLine($"UserExp 적립 : {exp}");
userExp = userExp + exp;
}
static void Main(string[] args)
{
PlusDelegate killMonster = PlusCoin;
killMonster += PlusPoint;
killMonster += PlusExp;
killMonster(100, 30, 40);
// 결과 확인
Console.WriteLine($"UserCoin : {userCoin}, UserPoint : {userPoint}, UserExp : {userExp}");
}
}
}
delegate를 다루는 부분을 살펴보겠습니다.
PlusDelegate killMonster = PlusCoin;
killMonster += PlusPoint;
killMonster += PlusExp;
killMonster(100, 30, 40);
PlusDelegate를 동일하게 초기화하고, PlusCoin 메서드를 등록해줬습니다.
그 다음에 PlusPoint와 PlusExp 메서드도 추가로 등록해줬습니다.
이제 저 3개의 메서드는 killMonster 대리자를 한번만 호출해도 다 동작을 하게 되는 것입니다.
4. delegate 활용(메서드 매게변수 전달)
delegate는 메서드를 호출 할 때 메서드의 매개변수로 전달 할 수 있습니다.
장점은 event 포스팅에서 설명을 하고 여기서는 어떻게 사용하는지까지만 살펴보겠습니다.
예제 소스입니다.
using System;
namespace ConsoleApplication
{
// delegate 선언
public delegate void PlusDelegate(int score);
public class Program
{
static int userCoin = 0;
// coin 적립 메서드
static void PlusCoin(int score)
{
Console.WriteLine($"UserCoin 적립 : {score}");
userCoin = userCoin + score;
}
static void PrintCoin(PlusDelegate plusDelegate)
{
plusDelegate(100);
Console.WriteLine($"UserCoin : {userCoin}");
}
static void Main(string[] args)
{
// delegate 초기화/ PlusCoin 메서드 등록
PlusDelegate killDelegate = PlusCoin;
// delegate 를 매개변수로 메서드 호출
PrintCoin(killDelegate);
}
}
}
// delegate 초기화/ PlusCoin 메서드 등록
PlusDelegate killDelegate = PlusCoin;
// delegate 를 매개변수로 메서드 호출
PrintCoin(killDelegate);
deledate를 초기화하고 동일하게 메서드를 등록합니다.
PrintCoin이라는 메서드를 호출할 때, 매개변수로 killDelegate 매개변수를 넘깁니다.
static void PrintCoin(PlusDelegate plusDelegate)
{
plusDelegate(100);
Console.WriteLine($"UserCoin : {userCoin}");
}
호출된 메서드에서 delegate를 사용할 수 있습니다.
5. delegate 활용(event)
이벤트(event) 별도 포스팅으로 정리했습니다.
'Developer > C#, 닷넷' 카테고리의 다른 글
C# Docker Environment.GetEnvironmentVariable (환경변수) 사용 (0) | 2022.08.18 |
---|---|
C# event 사용(delegate) (0) | 2022.08.16 |
C# 객체(Object), 클래스(Class), 인스턴스(Instance) 차이 비교 (0) | 2022.08.12 |
C# JSON 활용하기(직렬화, 역직렬화) (1) | 2022.08.11 |
C# 프로젝트 생성, Hello World 출력 (0) | 2022.08.10 |
댓글