delegate 2. 사용 방법
C#의 대리자는 함수를 변수처럼 사용하는 방법일 뿐이다.
C/C++ 에서는 함수 포인터의 개념과 비슷하고, 대부분의 언어에서 Callback(콜백) 개념으로 구현되어 있다.
대리자 선언
1. 선언방법
델리게이트_키워드 함수_반환형 델리게이트_이름(함수_시그니처);
delegate return_type delegate_name(int num1, int num2);
[.NET Frame 1.0]
델리게이트_키워드 함수_반환형 델리게이트_이름 = new 델리게이트_키워드(함수_이름)
delegate return_type delegate_name = new delegate(funtion);
[.NET Frame 2.0]
델리게이트_키워드 함수_ 반환형 델리게이트_이름 = 함수_이름
delegate void delegate_name = funtion;
2. 시그니처
대리자의 시그니처(매개변수 타입, 매개변수 갯수, 리턴 타입)와
함수의 헤더(function header)가 동일해야 하는 이유는,
이전 포스트의 [매개변수 사용법 2. 객체 전달] 에서와 같이, 대리자는 컴파일러에 의해 특별한 클래스로 변환된다.
대리자와 함수
대리자는 함수를 변수처럼 사용하는 방법일 뿐이다.
대리자 변수 func을 실행하면서, 매개변수를 넘겨주면, func 변수는 연결된 Add_var( ) 함수를 실행한다.
이전 포스트를 응용하면, func 대리자 변수명을 아래와 같이 Calc_var( )함수를 실행하듯 사용 가능하다.
A func = new A(Add_var);
// 대리자 변수를 함수처럼 사용하기
Console.WriteLine("매개변수 사용법 4. 계산 결과: " + func(1,2));
예제 1
run은 대리자의 변수이지만, 연결된 함수를 실행하듯이 사용 가능하다.
namespace delegate_test2
{
delegate void A(int i);
class MainClass
{
static void Run1(int val)
{
Console.WriteLine("{0}", val);// 콘솔출력 : 1024
}
static void Run2(int value)
{
Console.WriteLine("0x{0:X}", value);// 콘솔출력 : 0x800
}
static void Main(string[] args)
{
A run = run = new A(Run1); // [.NET Frame 1.0]
run(1024); // 대리자 변수명 run 사용
run = Run2; //[.NET Frame 2.0]
run(2048);
}
}
}
예제 2
namespace delegate_test3
{
class MySort
{
// 델리게이트 CompareDelegate 선언
public delegate int CompareDelegate(int i1, int i2);
public static void Sort(int[] arr, CompareDelegate comp)
{
if (arr.Length < 2)
return;
Console.WriteLine("함수 Prototype: " + comp.Method);
int ret;
for (int i = 0; i < arr.Length - 1; i++)
{
for (int j = i + 1; j < arr.Length; j++)
{
// 오름차순, 기준값과 다음값의 차가 음수면, 다음값이 " 큰 수" 이므로 교환
// 내림차순, 기준값과 다음값의 차가 양수면, 다음값이 "작은 수" 이므로 교환
ret = comp(arr[i], arr[j]);
if (ret == -1)
{
// 교환
int tmp = arr[j];
arr[j] = arr[i];
arr[i] = tmp;
}
Display(arr);
}
}
Display(arr);
}
static void Display(int[] arr)
{
foreach (var i in arr)
Console.Write(i + " ");
Console.WriteLine();
}
}
class Program
{
static void Main(string[] args)
{
(new Program()).Run();
}
void Run()
{
int[] unsortedList = { 3, 7, 2, 10, 1, 21, 6 };
// 오름차순으로 정렬
MySort.CompareDelegate compDelegate = AscendingCompare;
MySort.Sort(unsortedList, compDelegate);
// 내림차순으로 정렬
compDelegate = DescendingCompare;
MySort.Sort(unsortedList, compDelegate);
}
// CompareDelegate 델리게이트와 동일한 Prototype
int AscendingCompare(int num1, int num2)
{
if (num1 == num2)
return 0;
return (num1 - num2) > 0 ? -1 : 1;
}
// CompareDelegate 델리게이트와 동일한 Prototype
int DescendingCompare(int num1, int num2)
{
if (num1 == num2)
return 0;
return (num1 - num2) > 0 ? 1 : -1;
}
}
}