닷넷 API에 내장된 제네릭 대리자인 Action, Func, Predicate를 정리해보자
대리자 | 요약 |
Action | 반환값이 없는 메서드를 대신 호출 |
Func | 매개변수와 반환값이 있는 메서드를 대신 호출 |
Predicate | 매개변수에 대한 bool 값을 반환하는 메서드를 대신 호출 |
Action<T> 대리자
반환값이 없는 메서드를 대신 호출하는 제네릭 대리자로 주로 출력 등과 엮어서 사용할 수 있다.
class DelegatePractice
{
static void Main()
{
//Action 대리자 생성 : 반환값이 없으므로 인자는 모두 매개변수
Action<string> printf = Console.Write;
Action<int, int> printAdd = (int a, int b) => Console.WriteLine(a + b);
//대리자를 통한 호출
printf("Hello Action!\n");
printAdd(3, 6);
}
}
//출력 : Hello Action! 9
Action 제네릭 대리자를 활용해 C의 printf를 만들어보았다. 반환값이 없는 메서드를 대상으로 하기에 Action의 인자는 모두 매개변수의 타입이라고 볼 수 있다.
Func<T> 대리자
Func<매개변수 형식, 반환값 형식>로 매개변수와 반환값 형식이 있는 메서드를 대신 호출할 수 있다.
class DelegatePractice
{
static void Main()
{
//Func 대리자 생성 : 가장 마지막 인자는 반환값의 타입
Func<double, double> sqrt = Math.Sqrt;
//대리자를 통한 호출
Console.WriteLine(sqrt(4));
//첫번째, 두번째 인자는 매개변수의 타입을 나타낸다
Func<int, int, int> max = Math.Max;
//대리자를 통한 호출
Console.WriteLine(max(3,9));
//이미 있는 메서드 이외에도 무명 메서드(지난 포스팅 참고)와 람다 식으로 만들 수 있다.
Func<int, double> lambda = x => x * 1.5f;
//대리자를 통한 호출
Console.WriteLine(lambda(3));
}
}
//출력 : 2 9 4.5
매개변수가 2개일 경우, Func<매개변수1 타입, 매개변수2 타입, 반환값 타입>이다. Func<T>를 사용하면 별다른 델리게이트 선언 없이도 곧바로 람다식을 활용한 함수를 이용할 수 있다.
Predicate<T> 대리자
매개변수로 타입을 받아서 특정한 로직을 수행한 후 결과를 bool형으로 반환하는 메서드를 대신 호출한다.
class DelegatePractice
{
static void Main()
{
//Predicate 제네릭 대리자 생성
Predicate<string> isNullOrEmpty = String.IsNullOrEmpty;
//대리자를 통한 호출
Console.WriteLine(isNullOrEmpty(null));
//Predicate 제네릭 대리자를 메서드의 매개변수 형식으로 활용 가능
static string checkNum (Predicate<int> target)
{
for(int i = 1; i<50; i++)
{
if (target(i)) return $"Checked : {i}";
}
return "Nothing Checked";
}
//대리자 인자로 람다식을 통한 조건을 부여 가능
var checkStr = checkNum(v => v % 37 == 0);
Console.WriteLine(checkStr);
}
}
//출력 : True Checked : 37
위의 예제처럼 Predicate<T> 제네릭 대리자는 매개변수에 대리자 형식을 사용하는 것으로, 원하는 조건을 인자로 기입할 수 있도록 해준다. 이는 메서드의 매개변수를 확장해서 람다식을 인자로 받아들일 수 있게 해준다. Func<T> 제네릭 대리자 또한 매개변수의 형식으로 지정할 수 있으며, 이를 활용하는 것으로 메서드의 매개변수로 람다식을 받아 계산한 후 출력하는 유연한 메서드를 만들 수 있다.
매개변수에 메서드 전달하기
람다 식을 인자로 받는 대리자 형식을 매개 변수로 사용하는 것으로, 좀 더 유연한 메서드를 작성할 수 있다. 람다식은 물론 이미 작성된 메서드 역시 인자로 받을 수 있다.
class DelegatePractice
{
static void Main()
{
//매개변수 형식으로 Func<T> 제네릭 대리자 형식을 지정
void Calc(int a, int b, Func<int, int, int> calc) => Console.WriteLine(calc(a, b));
//람다식과 혼합해 사용하는 것으로 좀 더 유연한 메소드가 만들어졌다
Calc(2, 7, (a, b) => a + b);
Calc(5, 6, (a, b) => a * b);
//람다식을 사용하지 않는 메소드
int Minus(int a, int b)
{
return (a > b) ? a - b : b - a;
}
//다른 메서드 역시 인자로 받아진다.
Calc(1, 9, Minus);
}
}
//출력 : 9 30 8
'C#' 카테고리의 다른 글
[C#] 생성자(Constructor)와 소멸자(Destructor) (0) | 2024.04.29 |
---|---|
[C#] 스레드(Thread)와 동기화(lock), 병렬 처리 API(TPL) (0) | 2024.04.29 |
[C#] 람다 식(=>), 입력 매개 변수와 자연 형식 (0) | 2024.04.29 |
[C#] 이벤트(Event) (0) | 2024.04.26 |
[C#] 대리자(Delegate; 델리게이트)와 무명 메서드(+람다식 기초) (1) | 2024.04.26 |
[C#] 참조 매개 변수, ref와 out의 차이점 (0) | 2024.04.25 |
[C#] 값 형식과 참조 형식, 박싱과 언박싱(힙 메모리), is 연산자와 as 연산자 (0) | 2024.04.25 |
[C#] 다차원 배열과 가변 배열(C/C++ 문법과 차이점) (0) | 2024.04.25 |