C# 中的 Action 和 Func 委托:简化代码的利器
在C#中,委托(Delegate
)是一种引用类型,它允许我们将方法作为参数传递或存储在变量中。Action
和 Func
是 .NET 框架
中预定义的两种泛型委托,它们可以显著简化代码的编写,尤其是在需要传递方法或处理回调时。本文将详细介绍 Action
和 Func
的用法,并通过实际示例帮助你更好地理解它们。
1、什么是 Action 和 Func?
Action 委托
Action
是一个不带返回值
的委托,它可以接受最多 16 个参数。Action 通常用于表示一个无返回值
的方法。
Action 的特点:
无返回值。
可以不带参数,也可以带参数(最多 16 个)。
常用于事件处理或执行某些操作。
Action 例子:
// 无参数的 Action
Action sayHello = () => Console.WriteLine("Hello, World!");
sayHello();
// 带一个参数的 Action
Action<string> greet = name => Console.WriteLine($"Hello, {name}!");
greet("Alice");
// 带多个参数的 Action
Action<int, int> printSum = (a, b) =>
{
int sum = a + b;
Console.WriteLine($"Sum of {a} and {b} is {sum}");
};
printSum(10, 20);
Func 委托
Func
是一个带返回值
的委托,它可以接受最多 16 个参数
,并返回一个指定类型的值。Func
通常用于表示一个有返回值
的方法。
Func 的特点:
有返回值。
可以不带参数,也可以带参数(最多 16 个)。
常用于 LINQ 查询
或需要返回值
的场景。
Func 例子:
// 不带参数的 Func
Func<string> func = () => "stringTest";
// 带一个参数的 Func
Func<int, int> funInt = a => a + 1;
// 带两个参数的 Func
Func<string, int, string> funMulti = (intRes, stringRes) =>
{
return $"{intRes.ToString()} + {stringRes}";
};
2、Action 和 Func 的实际应用
①. 使用 Func 进行集合操作
Func
在 LINQ 查询中
非常常见。例如,我们可以使用 Func
对集合进行筛选、排序和计算:
List<int> list = new List<int> { 1, 23, 45, 27, 68, 78, 45, 12, 3, 89, 7, 5, 43, 23, 4, 129, 267 };
// 筛选出集合中大于 4 的元素
List<int> resList = list.Where(n => n > 4).ToList();
// 排序
resList.Sort();
// 输出结果
foreach (int res in resList)
{
Console.WriteLine(res);
}
②. 使用 Func 计算平均值
我们可以使用 Func
对对象集合进行复杂的计算,例如计算平均年龄:
List<UserInfo> userInfos = new List<UserInfo>()
{
new UserInfo { Id = 1, Name = "Test1", Age = 5 },
new UserInfo { Id = 2, Name = "Test2", Age = 6 },
new UserInfo { Id = 3, Name = "Test3", Age = 7 },
new UserInfo { Id = 4, Name = "Test4", Age = 8 },
new UserInfo { Id = 5, Name = "Test5", Age = 9 }
};
// 计算平均年龄
double avgAge = userInfos.Average(n => n.Age);
Console.WriteLine($"Average age: {avgAge}");
③. 使用 Action 处理事件
Action
可以用于简化事件处理程序的编写。例如:
button.Click += (sender, e) => Console.WriteLine("Button clicked!");
3、完整示例代码
以下是一个完整的示例,展示了 Action 和 Func
的多种用法:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Action__Func
{
internal class Program
{
static void Main(string[] args)
{
#region Action
// 无参数的 Action
Action sayHello = () => Console.WriteLine("Hello, World!");
sayHello();
// 带一个参数的 Action
Action<string> greet = name => Console.WriteLine($"Hello, {name}!");
greet("Alice");
// 带多个参数的 Action
Action<int, int> printSum = (a, b) =>
{
int sum = a + b;
Console.WriteLine($"Sum of {a} and {b} is {sum}");
};
printSum(10, 20);
#endregion
#region Func
// 不带参数的 Func
Func<string> func = () => "stringTest";
// 带一个参数的 Func
Func<int, int> funInt = a => a + 1;
// 带两个参数的 Func
Func<string, int, string> funMulti = (intRes, stringRes) =>
{
return $"{intRes.ToString()} + {stringRes}";
};
// Func 的应用
List<int> list = new List<int> { 1, 23, 45, 27, 68, 78, 45, 12, 3, 89, 7, 5, 43, 23, 4, 129, 267 };
List<int> resList = list.Where(n => n > 4).ToList();
resList.Sort();
foreach (int res in resList)
{
Console.WriteLine(res);
}
List<UserInfo> userInfos = new List<UserInfo>()
{
new UserInfo { Id = 1, Name = "Test1", Age = 5 },
new UserInfo { Id = 2, Name = "Test2", Age = 6 },
new UserInfo { Id = 3, Name = "Test3", Age = 7 },
new UserInfo { Id = 4, Name = "Test4", Age = 8 },
new UserInfo { Id = 5, Name = "Test5", Age = 9 }
};
var userList = userInfos.OrderBy(n => n.Id).ToList();
double avgAge = userInfos.Average(n => n.Age);
foreach (UserInfo userInfo in userList)
{
Console.WriteLine($"{userInfo.Name} {userInfo.Id} {userInfo.Age}");
}
#endregion
Console.ReadKey();
}
}
public class UserInfo
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
}
4、总结
Action 和 Func
是 C# 中非常强大的委托类型,它们可以显著简化代码的编写,尤其是在需要传递方法或处理回调时。Action
适用于无返回值的方法,而 Func
适用于有返回值的方法。通过合理使用 Action
和 Func
,我们可以编写出更加简洁、灵活和高效的代码。