当前位置: 首页 > news >正文

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则覆盖了大多数需要委托的场景。

http://www.jsqmd.com/news/194049/

相关文章:

  • 从参考音频上传到音频输出:GLM-TTS全流程操作手册
  • 米尔T113核心板的农机中控屏显方案解析
  • 构建GLM-TTS用户成长体系:等级、勋章与激励机制
  • 2026年1月苏州激光切管机标杆厂家最新推荐:科晟恒激光,高精度激光切管机、零尾料激光切管机、薄壁管激光切管机、半自动上料激光切管机、坡口激光切管机、开启高精度、高效率管材加工新纪元 - 海棠依旧大
  • 2026年西安景观水幕公司推荐榜:水景水幕水帘/桥梁水幕/数字水幕/室内水幕景观/秋千水幕/文字水幕/舞台数字水幕/拉线水幕帘/数码水幕公司精选 - 品牌推荐官
  • 基于Spring Boot+vue的畜牧养殖牛场管理系统的设计与实现
  • Python虚拟环境深度解析:从virtualenv到virtualenvwrapper
  • 零样本语音合成新突破:GLM-TTS技术深度解析与应用指南
  • 力高的鱼缸铝型材厂家有哪些?鱼缸铝型材源头厂家怎么选?佛山腾翔铝业实力解析 - mypinpai
  • 移动端点击事件300ms延迟如何去掉?原因是什么?
  • 如何用GLM-TTS生成企业宣传片旁白提升品牌形象
  • 基于SpringBoot+Vue的高校课程考勤成绩管理系统
  • 优质铜箔胶带制造商盘点:工艺成熟+客户口碑(25年榜单) - 品牌排行榜
  • 如何评估GLM-TTS生成语音的质量?主观与客观指标结合
  • GLM-TTS与Cockpit CMS结合:开发者友好的内容平台
  • 使用Railway简化GLM-TTS云服务部署流程
  • [Windows] Android实时投屏控制软件:QtScrcpy v3.3.3
  • GLM-TTS能否处理古文文言文?经典文献诵读测试
  • springboot vue村民选举投票信息管理系统
  • 使用Netlify Functions扩展GLM-TTS后端能力
  • GLM-TTS与Directus CMS结合:开源内容管理新选择
  • springboot+vue企业员工在线办公自动化oa系统
  • 解决TTS延迟难题:GLM-TTS流式推理性能实测报告
  • 2025有经验的业务流程数字化方案公司推荐:PMP认证团队(防坑指南) - 品牌排行榜
  • SpringBoot+VUE企业员工居家在线办公文档管理系统的设计与实现
  • GLM-TTS支持哪些语言?中英文混合合成效果实测分析
  • springboot+vue心理咨询预约系统
  • srm系统有哪些公司值得选:头部厂商深度对比(实力榜) - 品牌排行榜
  • [Windows] 老司机专用播放器 SecureVault Player V0.8.9
  • 五大核心场景优质铝电解电容推荐清单:原装电解电容、固态铝电解电容、混合型铝电解电容、焊片式铝电解电容、牛角式铝电解电容选择指南 - 优质品牌商家