
Func와 Action의 차이점
Func와 Action은 C#에서 제공하는 델리게이트 타입이다.
델리게이트는 메서드를 참조하는 타입으로, 코드를 외부로부터 받아 실행할 수 있게 해준다.
두 타입은 구조는 비슷하지만 반환값 유무에 따라 역할이 다르다.
Func
- 반환값이 있는 델리게이트다.
- 기본 형태는 Func<in T1, ..., out TResult>이다.
- 매개변수들을 입력받아, 마지막 타입으로 명시된 반환값을 리턴한다.
예시:
Func<int, int, int> add = (a, b) => a + b;
int result = add(3, 4); // result = 7
위는 int 두 개를 받아서 int 하나를 반환하는 Func이다.
Action
- 반환값이 없는 델리게이트다.
- 기본 형태는 Action<in T1, ...>이다.
- 입력받은 매개변수로 작업만 수행하고 반환값은 없다.
예시:
Action<string> greet = name => Console.WriteLine($"Hello, {name}!");
greet("Alice"); // 콘솔에 "Hello, Alice!" 출력
이 코드는 문자열을 입력받아 인사 메시지를 출력하지만 아무것도 반환하지 않는다.
Func를 이용하여 람다를 받아 실행하는 예제
다음은 Func를 사용하여 외부에서 람다를 전달받아 실행하는 예제이다.
using System;
class Program
{
static Func<int, int> _sessionFactory;
static void Main(string[] args)
{
_sessionFactory = x => x * x; // 입력값의 제곱을 반환하는 람다 대입
ExecuteDynamicFunc();
_sessionFactory = x => x + 10; // 입력값에 10을 더하는 람다로 교체
ExecuteDynamicFunc();
}
static void ExecuteDynamicFunc()
{
int input = 5;
int result = _sessionFactory.Invoke(input);
Console.WriteLine($"입력: {input}, 결과: {result}");
}
}
출력 결과:
입력: 5, 결과: 25
입력: 5, 결과: 15
설명
- Func<int, int> 타입을 가진 _sessionFactory 필드를 만든다.
- 외부(Main)에서 원하는 로직을 람다 식으로 주입한다.
- ExecuteDynamicFunc 메서드에서는 _sessionFactory.Invoke(input)를 통해 주입된 함수를 실행한다.
Func 확장 예제: 매개변수가 여러 개인 경우
두 개의 숫자를 입력받아 결과를 반환하는 경우에도 같은 패턴을 사용할 수 있다.
using System;
class Program
{
static Func<int, int, int> _sessionFactory;
static void Main(string[] args)
{
_sessionFactory = (x, y) => x + y; // 덧셈
ExecuteDynamicFunc();
_sessionFactory = (x, y) => x * y; // 곱셈
ExecuteDynamicFunc();
}
static void ExecuteDynamicFunc()
{
int a = 3;
int b = 7;
int result = _sessionFactory.Invoke(a, b);
Console.WriteLine($"입력: {a}, {b}, 결과: {result}");
}
}
출력 결과:
입력: 3, 7, 결과: 10
입력: 3, 7, 결과: 21
설명
- _sessionFactory에 (int, int) => int 형태의 람다를 주입한다.
- 원하는 연산(덧셈, 곱셈 등)을 외부에서 유연하게 변경할 수 있다.
Action 확장 예제: 반환값 없이 작업만 수행하는 경우
반환값이 필요 없다면 Action을 사용할 수 있다.
using System;
class Program
{
static Action<int, int> _sessionFactory;
static void Main(string[] args)
{
_sessionFactory = (x, y) => Console.WriteLine($"{x} + {y} = {x + y}");
ExecuteDynamicAction();
}
static void ExecuteDynamicAction()
{
int a = 4;
int b = 5;
_sessionFactory.Invoke(a, b);
}
}
출력 결과:
4 + 5 = 9
Func 비동기 확장 예제: 비동기로 동작하는 경우
Func는 Task를 반환하는 비동기 함수도 받을 수 있다.
using System;
using System.Threading.Tasks;
class Program
{
static Func<int, Task<int>> _sessionFactory;
static async Task Main(string[] args)
{
_sessionFactory = async x =>
{
await Task.Delay(500); // 0.5초 대기
return x * 2;
};
await ExecuteDynamicFuncAsync();
}
static async Task ExecuteDynamicFuncAsync()
{
int input = 5;
int result = await _sessionFactory.Invoke(input);
Console.WriteLine($"입력: {input}, 결과: {result}");
}
}
출력 결과:
입력: 5, 결과: 10
'C# > TIL(Today I Learned)' 카테고리의 다른 글
| 2025-05-06 <클래스를 전역에서 접근하고 싶을 때> (0) | 2025.05.06 |
|---|---|
| 2025-04-26 <형변환> (0) | 2025.04.26 |
| 2025-04-24 <박싱과 언박싱> (0) | 2025.04.24 |
| 2025-04-23 <const와 readonly> (0) | 2025.04.23 |
| 2025-04-19 <ArraySegment> (0) | 2025.04.19 |
댓글