Action<T> 无返回值,用于执行操作;Func<T, TResult> 有返回值,用于计算结果。二者在事件处理、LINQ、回调和行为注入等场景中各司其职,提升代码简洁性与可维护性。

Action<T> 和 Func<T, TResult> 是 C# 中两个常用的泛型委托,它们都用于封装方法,但用途和结构不同。理解它们的区别并掌握实际应用场景,有助于写出更简洁、可维护的代码。
基本定义与返回值差异
Action 和 Func 最核心的区别在于是否具有返回值:
- Action<T> 代表一个接受一个参数(类型为 T)且没有返回值的委托,即返回类型为 void。
- Func<T, TResult> 代表一个接受一个参数(类型为 T)并返回指定类型(TResult)结果的委托。
例如:
Action<string> print = s => Console.WriteLine(s);print("Hello"); // 输出:Hello
Func<int, int> square = x => x * x;
int result = square(5); // result = 25
常见使用场景对比
两者在实际开发中广泛应用于事件处理、集合操作、依赖注入等场景。
Action 的典型应用:
- 执行某种操作而不关心结果,比如日志记录、消息通知。
- 作为回调函数传递给其他方法,例如集合遍历中的 List.ForEach(action)。
names.ForEach(name => Console.WriteLine($"Hello, {name}"));
Func 的典型应用:
- 需要对输入进行转换或计算后返回结果,比如数据映射、条件判断。
- LINQ 查询中大量使用 Func,如 Where、Select 等。
var squares = numbers.Select(x => x * x).ToList(); // 使用 Func
灵活应对多参数情况
这两个委托都有多个泛型重载版本:
- Action 支持最多 16 个参数的重载(如 Action<T1, T2>),但始终无返回值。
- Func 同样支持多个输入参数,最后一个类型参数始终是返回类型,例如 Func<int, int, bool> 表示两个 int 输入,返回 bool。
例如:
Action<string, int> logEntry = (msg, level) => Console.WriteLine($"[{level}] {msg}");logEntry("Error occurred", 3);
Func<string, int, string> formatMsg = (s, n) => $"{s}: {n} times";
string output = formatMsg("Clicked", 5); // "Clicked: 5 times"
在自定义方法中使用委托提升灵活性
将 Action 或 Func 作为参数传入方法,可以实现行为的动态注入,增强代码复用性。
void ProcessData(List<int> data, Action<int> onItemProcessed, Func<int, bool> filter){
foreach (var item in data)
{
if (filter(item))
{
onItemProcessed(item);
}
}
}
调用时可根据需要传入不同的逻辑:
ProcessData(numbers,item => Console.WriteLine($"Processing {item}"),
x => x % 2 == 0 // 只处理偶数 );
基本上就这些。Action 适合“做点事”,Func 适合“算个结果”。合理选用能让代码更清晰、更具扩展性。









