C# delegate(델리게이트)
메서드를 참조
하는 참조형 변수
로 다른 언어에서는 함수 포인터
에 해당한다.
델리게이트를 사용하면 메서드를 변수로 저장하고 전달할 수 있으며
이를 통해 콜백 메커니즘
, 이벤트 처리
등을 구현할 수 있다.
사용 방법
-
델리게이트를 선언 :
델리게이트의 반환형태와 매개변수를 정의 하여
델리게이트 타입을 선언
한다. -
델리게이트 객체 생성 :
선언한 델리게이트 타입을 기반으로 인스턴스를 생성 이때 객체는 메서드를 참조할 수 있다. (비워도 된다.)
이떄 메서드는 시그니처
(반환형태와 매개변수)가 일치
해야 한다. -
델리게이트 호출: 델리게이트 객체를 호출해서 참조하고 있는 메서드를 실행.
//1
delegate void DelegateName<T> (T _parameter);
//2
static void PrintNumber(int num){
Console.WriteLine($"Number : {num}");
}
DelegateName<int> del = new DelegateName<int>(PrintNumber);
//3
del(10);
-
+= 연산자 사용
+= 연산자를 사용해서 델리게이트에 참조 메서드를 추가할 수 있다.
만약 델리게이트가 여러개의 메소드를 참조하고 있다면
델리게이트를 호출할때 참조중인 메소드가 전부 차례대로 실행된다.
-
여러개의 메서드 참조
델리게이트가 여러 개의 메서드를 참조하는 경우,
내부적으로 참조한 메서드들을
다중 연결 리스트
로 저장한다.그래서 호출될때 참조 메서드들을 순서대로 호출할 수 있다.
내부의 연결리스트에 직접 접근하는 기능은 제공되지 않는다.
Generic delegate Type
C#에서 제공하는 제네릭 델리게이트 타입들이다.
1. Action<T>
메서드에서 입력값을 받아서 반환값이 없는 작업을 수행
할 때 사용됩니다.
다수의 인수를 받을수 있다.
public delegate void Action<T>(T obj);
class Program
{
static void Main()
{
Action<int> action = Func1;
action(10);
}
static void Func1(int num)
{
Console.WriteLine($"Func : {num}");
}
}
2. Func<T, TResult>
메서드에서 입력값을 받아서 특정 타입의 결과값을 반환
할 때 사용됩니다.
다수의 인수를 받을수 있다.
public delegate TResult Func<T, TResult>(T arg);
class Program
{
static void Main()
{
Func<int,int,int> func = Func2;
Console.WriteLine($"Func2 : {func(11, 12)} ");
}
static int Func2(int num1, int num2)
{
return num1 + num2;
}
}
3. Predicate<T>
조건을 표현하는 메서드를 참조
하여 bool 타입의 결과 값을 반환
합니다.
하나의 인수 만을 받을수 있다.
public delegate bool Predicate<T>(T obj);
class Program
{
static void Main()
{
Predicate<int> func = Func3;
Console.WriteLine($"Func2 : {func(11)} ");
}
static bool Func3(int num1)
{
return num1 > 2;
}
}
람다식
람다식 (Lambda Expressions)는 간결하고 간단한 익명 함수
를 만들 수 있도록 도와주는 기능이다.
코드를 더 가독성 있고 유연하게 만들 수 있따.
(parameters) => expression
매개 변수가 하나 인경우 ()를 생략할 수 있고, 여러개 인 경우 () 내부에서 ,
로 구분한다.
expression
는 람다식의 본문으로 수행할 동작을 표현한다.
class Program
{
delegate int AddDelegate(int a, int b);
static void Main(){
AddDelegate add1 = (x,y) => x + y;
Action<int, int> add2 = (x, y) => Console.WriteLine($"{x} + {y} = {x + y}");
Func<int, int, int> add3 = (x, y) => x + y;
Predicate<int> compare = (x) => x == 10;
int result1 = add1(5,10);// 15를 리턴
add(5, 5); // 5 + 5 = 10 을 출력
int result2 = add2(10, 10); // 20을 리턴
bool result3 = compare(10); //true를 리턴
}
}
람다식은 익명 함수
이기 때문에 직접 호출할 수 없고, 이처럼 delegate가 람다식을 참조하여 람다식을 사용할 수 있다.