서론
C#을 학습하면서 가장 흥미로웠던 개념 중 하나가 바로 대리자(Delegate)입니다. 처음에는 단순히 "메소드에 대한 참조"라는 개념이 와닿지 않았지만, 콜백 패턴을 이해하면서 그 강력함을 깨달을 수 있었습니다. 이번 포스트에서는 C#의 대리자에 대해 자세히 알아보겠습니다.
본론
1. 대리자(Delegate)의 이해
1.1 대리자란 무엇인가?
대리자는 C#에서 메소드를 일급 객체로 취급할 수 있게 해주는 타입입니다. 다시 말해, 메소드를 변수에 할당하고, 매개변수로 전달하고, 반환할 수 있게 해주는 것입니다. 대리자의 선언 구문은 다음과 같습니다:
public delegate int Calculator(int a, int b);
C#
복사
이 선언은 컴파일러에게 다음을 알려줍니다:
•
반환 타입이 int인 메소드를 참조할 수 있음
•
두 개의 int 매개변수를 받는 메소드만 참조 가능
1.2 대리자의 활용
대리자를 사용하는 기본적인 패턴은 다음과 같습니다:
public class MathOperations
{
public static int Add(int a, int b) => a + b;
public static int Multiply(int a, int b) => a * b;
public static void Main()
{
// 1. 대리자 인스턴스 생성
Calculator calc = new Calculator(Add);
// 2. 대리자를 통한 메소드 호출
int result = calc(10, 20); // Add(10, 20)과 동일
// 3. 다른 메소드로 교체
calc = Multiply;
result = calc(10, 20); // Multiply(10, 20)과 동일
}
}
C#
복사
2. 대리자의 필요성
2.1 유연한 설계
대리자는 "코드를 매개변수로 전달"할 수 있게 해줍니다. 이는 알고리즘의 일부를 유연하게 교체할 수 있게 해주는 강력한 기능입니다. 특히 다음과 같은 상황에서 유용합니다:
1.
콜백 구현
2.
이벤트 처리
3.
알고리즘의 일부를 매개변수화
public class Sorter<T>
{
public delegate int CompareDelegate(T x, T y);
public void Sort(T[] array, CompareDelegate compare)
{
for (int i = 0; i < array.Length - 1; i++)
for (int j = i + 1; j < array.Length; j++)
if (compare(array[i], array[j]) > 0)
{
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
C#
복사
2.2 일반화 대리자
제네릭 프로그래밍의 장점을 대리자에서도 활용할 수 있습니다. 일반화 대리자를 사용하면 타입에 독립적인 유연한 코드를 작성할 수 있습니다.
public delegate T Operation<T>(T a, T b);
// 사용 예시
Operation<string> concatenate = (a, b) => a + b;
Operation<int> add = (a, b) => a + b;
C#
복사
2.3 대리자 체인
대리자의 또 다른 강력한 기능은 여러 메서드를 하나의 대리자에 연결할 수 있다는 점입니다. 이를 대리자 체인 또는 멀티캐스트 대리자라고 합니다.
public delegate void Logger(string message);
public class LoggingExample
{
public static void ConsoleLog(string message) =>
Console.WriteLine($"Console: {message}");
public static void FileLog(string message) =>
File.AppendAllText("log.txt", $"File: {message}\\n");
public static void Main()
{
Logger log = ConsoleLog;
log += FileLog; // 체인 형성
// 두 메소드 모두 호출됨
log("테스트 메시지");
}
}
C#
복사
결론
다음 포스트에서는 대리자를 기반으로 하는 이벤트 시스템에 대해 알아보겠습니다. 이벤트는 대리자의 개념을 확장하여 객체 간 통신을 더욱 유연하게 만들어주는 메커니즘입니다.
참고 자료
•
박상현, "이것이 C#이다", 한빛미디어, 2023