Learning
When: 1학년 7월 8일
How:
원래 대리자에 대해서는 어느 정도 알고 있기는 했지만, event, 람다식 등 대리자를 완전히 이해해야 사용할 수 있는 문법들을 배우다 보니 자세히 공부해야 할 것 같아 공부하게 되었습니다.
Understanding:
- 대리자란?
대리자는 메서드를 담는 변수입니다. 대리자 변수를 만든 다음, 그 변수에 메서드들을
연결하면 변수에 메서드들이 담깁니다. 정확히 말하면 변수는 연결된 메서드들을 참조하는
것이고, 그 변수는 연결한 메서드들을 한 번에 실행시킬 수도 있습니다. - 어떻게 사용할까?
대리자를 쓰는 것은 조금 갈릴 수도 있지만 한번 알면 어렵지 않습니다.
일단 대리자는 일반적인 변수를 사용하는 것보다 조금 더 복잡한데, 매개변수와 반환 형식이
있는 타입을 먼저 선언한 다음 그 형식의 변수를 선언하여 메서드를. 그 이유는 대리자
타입을 만든 다음, 그 대리자 타입의 변수를 만들고, 그 변수에 메서드를 연결(대입,
복합 할당 연산자{+=, -=})하여 사용하기 때문입니다. 아래의 코드는
간단하게 대리자를 사용하는 코드인데, 순서대로 설명하자면- 대리자 변수의 타입을 만들어 줍니다. 대리자는 메서드를 담는 변수라는 것을 기억하고
계신다면 일단 메서드의 반환 형식과 매개 변수는 변수를 만들 때 정의가 돼야 한다는 것도
유추하실 수 있습니다. - 변수를 생성할 때는 그냥 다른 변수와 같이 접근 제한자, 타입을 정하고 변수명을 쓰면
됩니다. (전 짧은 코드를 위해 static으로 선언하여 인스턴스를 만들지 않았습니다.) - 반환 형식과 매개변수가 변수의 타입, 즉 아까 정한 델리게이트 타입의 설정과 같다면
변수에 매개 변수를 연결시킬 수 있습니다. - 마지막으로 tD(1, 2); 이런 식으로 대리자 변수를 메서드처럼 호출시킬 수도 있지만,
만약 변수가 null일 경우를 대비하여 ?.Invoke(); 메서드를 사용하면 변수가 null일 땐
실행이 안되고, null이 아닐 때는 실행되는 안전한 프로그램을 만들 수 있습니다.
- 대리자 변수의 타입을 만들어 줍니다. 대리자는 메서드를 담는 변수라는 것을 기억하고
internal class Program
{
private delegate void testDelegate(int a, int b); //대리자 타입 생성
private static testDelegate tD; //변수 생성
static void Main(string[] args)
{
tD += PlusMethod; // 복합 할당 연산자로 대입 (그냥 '='으로 대입도 가능합니다)
tD?.Invoke(1, 2); // 실행
}
private static void PlusMethod(int a, int b)
{
Console.WriteLine(a + b);
}
}
- 왜 사용할까?
메서드들을 한번에 여러 개 사용하는 것쯤은 그냥 메서드를 여러 번 호출시키는 메서드를
만드는 것으로 충분합니다. 하지만 대리자는 할 수 있는 일이 더 많을뿐더러, 여러 메서드를
동시에 호출하는 역할도 그냥 메서드로 하는 것보다 훨씬 잘할 수 있습니다. - 여러 메서드 동시에 호출하기
아래의 코드는 2개의 메서드를 동시에 호출하는 코드입니다. 여기서 대리자를 쓰지 않는다면
2개의 메서드를 실행하는 메서드를 따로 만들어야 하는데, 이것을 사용하면 유연성이 떨어진다는
것을 직관적으로 알 수 있고, +=, -=를 사용하지 못하기 때문에 실행 도중에 바꿀 수 없다는
대리자와 비교하면 큰 불편함이 생깁니다.
using System;
using System.Diagnostics;
namespace Test
{
internal class Program
{
private delegate void testDelegate(int a, int b);
private static testDelegate tD;
static void Main(string[] args)
{
Test1 test1 = new Test1();
Test2 test2 = new Test2();
tD += test1.PlusMethod;
tD += test2.MinusMethod;
tD?.Invoke(1, 2);
}
}
public class Test1
{
public void PlusMethod(int a, int b)
{
Console.WriteLine(a + b);
}
}
public class Test2
{
public void MinusMethod(int a, int b)
{
Console.WriteLine(a - b);
}
}
}
- 메서드의 인수로 메서드 넣기
아래 코드 처럼 대리자 타입을 만들어 두고 타입의 변수를 만든 다음, 그 변수를
인수로 넣어 메서드 내에서 실행시키는 것이
가능한데, 이것을 사용하는 방법 중에는 데미지 계산을 예시로 들겠습니다.
치명타 데미지, 버프 받았을 때 데미지, 일반 데미지를 계산하는 메서드가 있다고
가정해 보겠습니다. 그리고 데미지를 받는 메서드에서 데미지를 계산해야 할 때
메서드 자체를 인수로 주지 않는다면 오버로딩을 하거나 데미지를 받는 메서드를
여러 개 만들어야 할 것입니다. 하지만 메서드를 인수로 준다면 데미지 계산은
따로 인수로 받은 메서드로 하고, 따로 실행할 코드는 데미지를 받는 메서드 안에서
하는 방식을 사용할 수 있습니다.
using System;
using System.Diagnostics;
namespace Test
{
internal class Program
{
public delegate int testDelegate(int a, int b);
private static testDelegate tD;
static void Main(string[] args)
{
Test2 test2 = new Test2();
tD += test2.MinusMethod;
PlusMethod(1, tD);
}
private static void PlusMethod(int a, testDelegate b)
{
int c = b(1, 2);
Console.WriteLine(a + c);
}
}
public class Test2
{
public int MinusMethod(int a, int b)
{
Console.WriteLine(a - b);
return a - b;
}
}
}
Result: 예시로 든 코드 말고도 많은 활용도가 있으니 대리자에 대해서는 완벽하게 이해하는 것이 좋습니다.
'C#' 카테고리의 다른 글
| [C#] List (1) | 2025.07.13 |
|---|---|
| [C#] event 키워드 (1) | 2025.07.09 |
| [C#] bool 타입이 아닌 값을 반환 형식이 bool인 메서드에서 반환하기 (0) | 2025.07.02 |
| [C#] 문자열의 한 문자를 가져오기 (0) | 2025.06.28 |
| [C#] enum 키워드 (0) | 2025.06.25 |