이번 글에서는 Action, Func, Predicate에 대해 알아보겠습니다. 이 셋은 모두 미리 정의된 제너릭 델리게이트 입니다. 메서드를 변수처럼 담아서 전달할 때 사용되는 그릇이라 보시면 되는데 반환 타입이나 파라미터의 형태에 따라 다를 뿐입니다.
이 셋의 차이는 아래와 같습니다.
| 구분 | 반환 타입 | 파라미터 | 용도 |
|---|---|---|---|
| Action | void (없음) | 0 ~ 16개 | 단순히 작업을 실행할 때 |
| Func | 있음 (Generic) | 0 ~ 16개 | 결과를 계산하여 반환할 때 |
| Predicate | bool (참/거짓) | 1개 (고정) | 조건을 검사할 때 |
Action
Action의 특징은 반환 값이 없습니다(void). 말 그대로 어떠한 작업을 실행하는 데 사용합니다. 로그를 출력하거나, UI를 업데이트 하는 등 단순한 동작을 실행하는 데 사용합니다. Action는 아래와 같이 사용 가능합니다.
// Action, Action<param1, param2, ...>
// hi 출력
Action showHi = () => MessageBox.Show("hi"); // 파라미터가 없는 Action
showHi (); // 실행
// 입력된 문자열 출력
Action<string> showMsg => (msg) => MessageBox.Show(msg); // 파라미터가 1개인 Action<T>
showMsg("Hi");
// 입력된 시간, 문자열 출력
private void ShowMessage(DateTime time, string msg)
{
MessageBox.Show($"Time: {time}, Message: {msg}");
}
Action<DateTime, string> showMessage = ShowMessage;
showMessage(DateTime.Now, "hi");
아래는 github에 올린 Action 예제 프로그램 입니다. x, y 좌표를 움직이고, 움직이고 난 뒤 로그를 찍는 프로그램입니다.
Func
Func의 특징은 반환 값이 있다는 것입니다. 주의해야할 점은 제네릭의 마지막 타입이 반환 타입이라는 것입니다. 그래서 최소한 <> 안에 하나의 타입을 넣어야 합니다. Func의 사용 예시는 아래와 같습니다.
// Func<param1, param2, ..., return>
// int를 받아서 int를 반환 (입력: int, 반환: int)
Func<int, int> square = (num) => num * num;
int result = square(5); // 결과: 25
// 입력 없이 문자열만 반환 (반환: string)
Func<string> getCurrentTime = () => DateTime.Now.ToString();
string time = getCurrentTime();
아래는 github에 올린 Func 예제 프로그램 입니다. 좌측은 전체 학생을 표시하며 ID, 학생, 점수가 표시되고, 우측엔 특정 점수를 기준으로 합격자, 불합격자를 출력하는 학생을 출력하는 프로그램입니다.
Predicate
Predicate는 조건 검사라는 의도일 경우 사용하며 구조적으로는 Predicate<T>와 Func<T, bool>과 동일합니다. 둘 다 입력을 받고 반환한다는 시그니처는 같지만 predicate는 1개만 입력 받고, 반환 타입이 bool인 특징을 가집니다. Predicate보다 Func를 더 자주 사용되며, 마이크로소프트에서 LINQ를 만들면서 모든 델리게이트를 Action과 Func로 통일하였습니다.
| 구분 | Predicate | Func |
|---|---|---|
| 의미 | 조건 검사(검증)이라는 의도 | 입력을 받고 결과를 반환(범용) |
| 등장 시기 | .NET 2.0 | .NET 3.5 (LINQ와 함께 등장) |
| 호환성 | List<T>.Find, RemoveAll 등 구형 API | Where, Any, Count 등 LINQ 표준 |
사용 예제는 아래와 같습니다.
// Predicate<T>
// 홀짝 판단
Predicate<int> isEven = (num) => num % 2 == 0;
bool result = isEven(10); // True
// B로 시작하는 단어 찾기
List<string> names = new List<string> { "Apple", "Banana", "Cherry", "Date" };
Predicate<string> startsWithB = (name) => name.StartsWith("B");
string foundName = names.Find(startsWithB);
Console.WriteLine($"찾은 단어: {foundName}"); // 출력: Banana
예제는 스킵하도록 하겠습니다.
이상으로 Action, Func, Predicate에 대해 알아보았습니다.

