델리게이트 #1
델리게이트
타입에 값을 담듯이 메서드 자체를 값으로 갖는 타입이다.
public class Disk
{
public int Clean(object arg)
{
Console.WriteLine("Execute");
return 0;
}
}
Disk disk = new Disk();
// 메서드를 인자로 갖는 타입의 인스턴스 생성
[타입] cleanFunc = new [타입](disk.Clean);
이렇게 메서드를 가리킬 수 있는 타입을 C#에서 delegate 구문을 제공하며 델리게이트 타입을 만드는 방법은 일반적인 class 구문이 아닌 delegate 예약어로 표현한다.
[접근제한자] delegate [메서드의 반환 타입] (매개변수)
대상이 될 메서드의 반환 타입 및 매개변수 목록과 일치하는 델리게이트 타입을 정의한다.
정의 방법
int Clean (object arg);
-
대상 메서드의 반환값과 인자를 분리하고 식별자만 바꾼다.
// 관례적으로 델리게이트 타입의 이름은 끝에 Delegate 라는 접미사를 붙인다. int FuncDelegate(object arg);
-
그 상태에서 delegate 예약어를 추가한다.
delegate int FuncDelegate(object arg);
이렇게 정의된 FuncDelegate 타입은 int 반환값과 object 인자를 하나 받는 메서드를 가리킬 수 있다.
Disk disk = new Disk();
FuncDelegate cleanFunc = new FuncDelegate(disk.Clean);
일반 숫자형 타입처럼 대입할 수 있는 문법을 통해서 new를 사용하지 않고 더 쉽게 사용할 수 있다.
FuncDelegate cleanFunc = new FuncDelegate(disk.Clean);
FuncDelegate workFunc = disk.Clean();
이렇게 선언된 델리게이트는 변수에 저장된 메서드를 가리키고 그 메서드를 호출하는 역할을 한다.
Disk disk = new Disk();
FuncDelegate cleanFunc = disk.Clean;
// Clean 메서드를 직접 호출
disk.Clean(null);
// 델리게이트 인스턴스를 통해 Clean 메서드를 호출
cleanFunc(null);
인스턴스가 메서드를 호출할 수 있다는 점을 제외하면 델리게이트는 완전한 타입에 속하므로 배열도 만들 수 있고 시그니처가 동일한 메서드라면 인스턴스/정적 유형에 상관없이 모두 가리킬 수 있다.
사용예시
using System;
public class Mathematics
{
delegate int CalcDelegate(int x, int y);
static int Add(int x, int y) { return x + y; }
static int Subtract(int x, int y) { return x - y; }
static int Multiply(int x, int y) { return x * y; }
static int Divide(int x, int y) { return x / y; }
CalcDelegate[] methods;
public Mathematics()
{
// static 메서드를 가리키는 델리게이트 배열 초기화
methods = new CalcDelegate[] {
Mathematics.Add,
Mathematics.Subtract,
Mathematics.Multiply,
Mathematics.Divide
};
}
// methods 배열에 담긴 델리게이트를 opCode 인자에 따라 호출
public void Calculate(char opCode, int operand1, int operand2)
{
switch (opCode)
{
case '+':
Console.WriteLine("+: " + methods[0](operand1, operand2));
break;
case '-':
Console.WirteLine("-: " + methods[1](operand1, operand2));
break;
case '*':
Console.WriteLine("*: " + methods[2](operand1, operand2));
break;
case '/':
Console.WriteLine("/: " + methods[3](operand1, operand2));
break;
}
}
}
namespace ConsoleApp1
{
class Program
{
// 3개의 매개변수를 받고 void를 반환하는 델리게이트 정의
// 매개변수의 타입이 중요할 뿐 매개변수의 이름은 임의로 정할 수 있다.
delegate void WorkDelegate(char arg1, int arg2, int arg3);
static void Main(string[] args)
{
Mathematics math = new Mathematics();
WorkDelegate work = math.Calculate;
work('+', 10, 5);
work('-', 10, 5);
work('*', 10, 5);
work('/', 10, 5);
}
}
}
// 출력
// +: 15
// -: 5
// *: 50
// /: 2
델리게이트가 타입이라는 점으로 다음과 같은 중요한 특징을 가진다.
-
메서드의 반환값으로 델리게이트를 사용할 수 있다.
메서드의 반환값으로 메서드를 사용할 수 있다.
-
메서드의 인자로 델리게이트를 전달할 수 있다.
메서드의 인자로 메서드를 전달할 수 있다.
-
클래스의 멤버로 델리게이트를 정의할 수 있다.
클래스의 멤버로 메서드를 정의할 수 있다.