news 2026/4/18 10:03:43

C#中的Action、Func、Predicate委托

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C#中的Action、Func、Predicate委托

C# 委托详解:Action、Func 和 Predicate 的使用指南

一 Action

委托可以理解为数组,专门存放函数的数组
Action 委托表示一个不返回值的委托,那就表示只能存放不返回值的方法,即void方法

usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;namespaceC_之Action委托{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privatevoidForm1_Load(objectsender,EventArgse){}// Action 委托, 数组,专门存放函数,就能返回为空,不返回, 少写代码,进行了一些封装privatevoidbutton1_Click(objectsender,EventArgse){//xxxDel xx = new xxxDel(testFunc);//xx += testFunc;// 方式1//Action x = new Action(testFunc);// 方式2:第二种,简写Actionx2=testFunc;x2+=testFunc;x2();}/// <summary>/// 返回为空的函数/// </summary>publicvoidtestFunc(){MessageBox.Show("测试函数");}publicinttestFunc2(){return99;}publicstringtestFunc3(){return"OK";}}publicdelegatevoidxxxDel();}

二 Func

Func委托,必有返回值,且<>中最后一个参数表示返回值类型的委托

usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;namespaceC_之Func委托{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privatevoidbutton1_Click(objectsender,EventArgse){//Func<int> func = new Func<int>(testFunc2);//func += testFunc2;//func();// 方式1//Func<int, string> func = new Func<int, string>(testFunc4);// 方式2: 委托就是数组,专门存放函数方法的数组,增减//Func<int, string> func2 = testFunc4;//func2 += testFunc4;//func2 -= testFunc4;//string res = func2(678);Func<int,double,string>func=testFunc5;func(123,2.2);}/// <summary>/// 返回为空的函数 Action/// </summary>publicvoidtestFunc(){MessageBox.Show("测试函数");}/// <summary>/// 返回整数的函数 Func/// </summary>/// <returns></returns>publicinttestFunc2(){MessageBox.Show("99");return99;}/// <summary>/// 返回字符串的函数/// </summary>/// <returns></returns>publicstringtestFunc3(){return"OK";}/// <summary>/// 返回字符串的函数/// </summary>/// <returns></returns>publicstringtestFunc4(intx){MessageBox.Show("接受参数:"+x);return"接受参数:"+x;}publicstringtestFunc5(intx,doubley){MessageBox.Show("接受参数:"+x+"浮点数"+y);return"接受参数:"+x+"浮点数"+y;}}}

三 Predicate

predicate委托,存放返回值为bool true false的函数

usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;namespaceC_之Predicate委托{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privatevoidbutton1_Click(objectsender,EventArgse){//Predicate<int> predicate = new Predicate<int>(TestFunc);Predicate<int>predicate2=TestFunc;boolres=predicate2(12);MessageBox.Show(res.ToString());}// predicate委托,存放返回值为bool true false的函数/// <summary>////// </summary>/// <param name="a"></param>/// <returns></returns>publicboolTestFunc(inta){if(a>10){returntrue;}else{returnfalse;}}}}

委托(Delegate)是C#中实现面向对象编程中"方法作为参数"概念的重要机制。在C#中,有三种特别常用的预定义委托类型:Action、Func和Predicate。本文将详细介绍它们的用法和区别。

一、委托基础回顾

委托是一种类型安全的函数指针,它允许你将方法作为参数传递,或者将方法存储在数据结构中。委托可以指向:

  • 静态方法
  • 实例方法
  • 匿名方法(lambda表达式)

二、Action 委托

1. 基本概念

Action委托用于封装没有返回值的方法。它可以有最多16个输入参数。

2. 定义与使用

// 无参数的ActionActionsimpleAction=()=>Console.WriteLine("Hello, Action!");simpleAction();// 输出: Hello, Action!// 带一个参数的ActionAction<string>greetAction=name=>Console.WriteLine($"Hello,{name}!");greetAction("Alice");// 输出: Hello, Alice!// 带多个参数的ActionAction<int,int>addAction=(x,y)=>Console.WriteLine($"Sum:{x+y}");addAction(5,3);// 输出: Sum: 8

3. 实际应用示例

List<string>names=newList<string>{"Alice","Bob","Charlie"};// 使用Action遍历列表Action<string>processName=name=>{if(name.Length>4)Console.WriteLine($"Long name:{name}");};names.ForEach(processName);// 输出:// Long name: Alice// Long name: Charlie

三、Func 委托

1. 基本概念

Func委托用于封装有返回值的方法。它可以有最多16个输入参数,最后一个参数类型是返回值类型。

2. 定义与使用

// 无参数的Func (返回int)Func<int>randomNumber=()=>newRandom().Next(1,100);Console.WriteLine(randomNumber());// 输出1-100之间的随机数// 带参数的FuncFunc<int,int,int>addFunc=(x,y)=>x+y;Console.WriteLine(addFunc(5,3));// 输出: 8// 更复杂的Func示例Func<string,bool>isLongName=name=>name.Length>5;Console.WriteLine(isLongName("Alexander"));// 输出: True

3. 实际应用示例

List<int>numbers=newList<int>{1,2,3,4,5};// 使用Func转换列表Func<int,string>numberToString=num=>$"Number:{num}";List<string>stringNumbers=numbers.ConvertAll(numberToString);foreach(varstrinstringNumbers){Console.WriteLine(str);}// 输出:// Number: 1// Number: 2// ...

四、Predicate 委托

1. 基本概念

Predicate委托专门用于封装返回bool值的方法,通常用于条件判断。它接受一个输入参数。

2. 定义与使用

// Predicate基本用法Predicate<string>isLongNamePredicate=name=>name.Length>5;Console.WriteLine(isLongNamePredicate("Hello"));// 输出: FalseConsole.WriteLine(isLongNamePredicate("Hello World"));// 输出: True// 在List.Find方法中使用List<string>names=newList<string>{"Alice","Bob","Charlie","David"};stringfound=names.Find(name=>name.Length>4);Console.WriteLine(found);// 输出: Alice

3. 与Func<T, bool>的关系

实际上,Predicate和Func<T, bool>在功能上是等价的。Predicate是.NET Framework早期引入的,而Func是.NET 3.5引入的泛型委托系列的一部分。在新代码中,通常推荐使用Func<T, bool>代替Predicate。

五、综合比较

委托类型参数数量返回值典型用途
Action0-16void执行操作,无返回值
Func0-16最后一个参数类型需要返回值的计算或转换
Predicate1bool条件判断(可用Func<T,bool>替代)

六、高级用法:委托链

Action和Func都支持"委托链"操作,即可以将多个委托组合成一个调用序列。

ActiongreetInEnglish=()=>Console.WriteLine("Hello!");ActiongreetInSpanish=()=>Console.WriteLine("¡Hola!");ActiongreetInFrench=()=>Console.WriteLine("Bonjour!");// 组合委托ActioncombinedGreetings=greetInEnglish+greetInSpanish+greetInFrench;combinedGreetings();// 输出:// Hello!// ¡Hola!// Bonjour!// 也可以从链中移除combinedGreetings-=greetInSpanish;combinedGreetings();// 输出:// Hello!// Bonjour!

七、实际应用场景

  1. 事件处理:Action常用于简单事件处理
  2. LINQ操作:Func广泛用于LINQ的Select、Where等方法
  3. 回调机制:异步操作完成后通过Action或Func回调
  4. 策略模式:使用Func实现不同算法策略
  5. 验证逻辑:Predicate/Func<T,bool>用于验证条件

八、最佳实践

  1. 当不需要返回值时,优先使用Action
  2. 当需要返回值时,使用Func
  3. 避免过度使用复杂的委托链,保持代码可读性
  4. 对于简单的条件判断,考虑使用lambda表达式直接内联
  5. 在公共API设计中,考虑使用更具体的委托类型或接口而不是泛泛的Action/Func

九、完整示例

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;classProgram{staticvoidMain(){// Action示例Action<string>logMessage=message=>Console.WriteLine($"[LOG]{message}");logMessage("Application started");// Func示例Func<int,int,int>calculate=(x,y)=>{intsum=x+y;logMessage($"Calculated sum:{sum}");returnsum;};intresult=calculate(5,3);Console.WriteLine($"Result:{result}");// Predicate/Func<T,bool>示例List<string>names=newList<string>{"Alice","Bob","Charlie","David"};// 使用Predicate风格Predicate<string>longNamePredicate=name=>name.Length>4;varlongNames1=names.FindAll(longNamePredicate);// 使用Func风格(推荐)Func<string,bool>longNameFunc=name=>name.Length>4;varlongNames2=names.Where(longNameFunc).ToList();Console.WriteLine("Names longer than 4 characters:");longNames2.ForEach(name=>Console.WriteLine(name));}}

总结

Action、Func和Predicate是C#中非常强大且常用的委托类型,它们简化了方法作为参数传递的语法,使得代码更加简洁和灵活。理解它们的区别和适用场景可以帮助你编写更优雅、更高效的C#代码。记住,在新代码中,Predicate通常可以被Func<T,bool>替代,而Action和Func则覆盖了大多数需要委托的场景。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 8:07:02

零样本语音合成新突破:GLM-TTS技术深度解析与应用指南

零样本语音合成新突破&#xff1a;GLM-TTS技术深度解析与应用指南 在智能语音助手、虚拟主播和有声内容爆发式增长的今天&#xff0c;用户对“像人一样说话”的AI语音提出了更高要求——不仅要清晰自然&#xff0c;还得有个性、有情绪、能快速定制。然而&#xff0c;传统TTS系…

作者头像 李华
网站建设 2026/4/17 13:58:41

长文本合成卡顿?教你优化GLM-TTS参数提升生成效率

长文本合成卡顿&#xff1f;教你优化GLM-TTS参数提升生成效率 在有声书平台批量生成章节音频时&#xff0c;你是否遇到过这样的场景&#xff1a;输入一段300字的文本&#xff0c;系统“卡”在那里十几秒毫无响应&#xff0c;最终还因显存溢出崩溃&#xff1f;又或者&#xff0c…

作者头像 李华
网站建设 2026/4/17 17:00:30

数眼智能搜索 API VS 夸克搜索 API:AI 数据提取领域的特色交锋

在 AI 技术驱动数据价值爆发的当下&#xff0c;高质量数据提取成为 AI 应用落地的核心支撑。数眼智能搜索 API 与夸克搜索 API&#xff0c;凭借差异化技术路径与场景适配能力&#xff0c;在数据提取领域形成独特竞争力。本文将从技术内核、核心优势、场景适配三大维度&#xff…

作者头像 李华
网站建设 2026/4/18 8:06:47

救命神器!2026自考AI论文工具TOP9:开题报告全攻略

救命神器&#xff01;2026自考AI论文工具TOP9&#xff1a;开题报告全攻略 2026自考AI论文工具测评&#xff1a;精准匹配你的写作需求 在自考过程中&#xff0c;撰写开题报告和论文是每位考生必须面对的挑战。随着人工智能技术的不断进步&#xff0c;AI论文工具逐渐成为提升写作…

作者头像 李华
网站建设 2026/4/18 5:42:51

springboot+vue企业员工在线办公自动化oa系统

目录摘要关于博主开发技术介绍核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;摘要 基于SpringBoot和V…

作者头像 李华
网站建设 2026/4/18 8:59:00

基于spring boot+vue的智慧物业来访预约报修管理系统

目录智慧物业来访预约报修管理系统摘要关于博主开发技术介绍核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#x…

作者头像 李华