news 2026/4/15 18:41:46

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/15 18:38:56

GLM-TTS情感控制技巧:如何让合成语音更自然生动

GLM-TTS情感控制技巧&#xff1a;如何让合成语音更自然生动 在虚拟主播的直播间里&#xff0c;一句平淡无奇的“欢迎新朋友”可能被淹没在弹幕洪流中&#xff1b;而如果这句问候带着恰到好处的热情与笑意&#xff0c;哪怕只是多了一丝语调起伏&#xff0c;也能瞬间拉近与观众的…

作者头像 李华
网站建设 2026/4/15 18:40:48

低成本实现高质量TTS:GLM-TTS在消费级显卡上的运行表现

低成本实现高质量TTS&#xff1a;GLM-TTS在消费级显卡上的运行表现 在智能语音助手、有声读物生成和虚拟偶像直播日益普及的今天&#xff0c;一个现实问题始终困扰着开发者与内容创作者&#xff1a;如何以合理的成本获得接近真人水平的语音合成效果&#xff1f;传统高质量TTS系…

作者头像 李华
网站建设 2026/4/15 18:38:20

语音合成也能有情感?揭秘GLM-TTS的情感迁移机制

语音合成也能有情感&#xff1f;揭秘GLM-TTS的情感迁移机制 在虚拟主播深情演绎故事、智能客服温柔安抚用户情绪的今天&#xff0c;我们早已不再满足于“机器能说话”——我们希望它说得动情。这背后&#xff0c;是语音合成技术从“发音准确”迈向“表达自然”的关键跃迁。而在…

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

构建GLM-TTS用户成长体系:等级、勋章与激励机制

构建GLM-TTS用户成长体系&#xff1a;等级、勋章与激励机制 在AI语音合成工具日益普及的今天&#xff0c;一个尖锐的问题摆在开发者面前&#xff1a;技术越强大&#xff0c;使用门槛反而越高。GLM-TTS这样的开源项目虽然具备方言克隆、情感迁移和音素级控制等前沿能力&#xff…

作者头像 李华
网站建设 2026/4/15 0:06:51

脑肿瘤检测数据集-3000张JPG医学图像-有肿瘤无肿瘤分类标注-用于AI算法训练与临床辅助诊断-脑肿瘤检测算法-脑肿瘤自动化检测技术-脑肿瘤检测模型-提升医学影像分析的自动化水平

脑肿瘤检测数据集分析报告 引言与背景 脑肿瘤检测是医学影像学领域的重要研究方向&#xff0c;早期准确诊断对患者治疗和预后至关重要。随着人工智能技术的发展&#xff0c;基于深度学习的脑肿瘤检测算法已成为辅助医生诊断的重要工具。本数据集为脑肿瘤检测算法的训练和评估…

作者头像 李华
网站建设 2026/3/31 20:14:47

Docker部署的web容器应用监控及自动重启

一、背景基于docker部署的诸多优点&#xff0c;目前越来越多的web应用采用docker方案部署&#xff0c;不论是采用何种语言开发的web后台应用&#xff0c;虽然开发团队会尽量的保障应用程序稳定、安全、性能优化&#xff0c;但总会在具体的实施过程中存在诸多不可控的运行故障&a…

作者头像 李华