c#如何使用Action和Func_c#Action和Func从入门到精通教程
C#中的Action与Func:从“天天见”到“真正会用”

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
开门见山,先说一个核心判断:Action 和 Func 压根不是什么需要“学透”才能用的高级概念。恰恰相反,它们是C#世界里最基础、最常用的委托类型,日常开发中处理事件、异步回调、LINQ查询或是依赖注入配置时,几乎天天都会打照面。真正让开发者感到困惑的,往往不是语法本身,而是两个更实际的问题:“眼下这个场景,我到底该用哪个?” 以及 “Func的参数顺序,到底该怎么记才不容易错?”。
什么时候必须用 Action,而不是自己写委托?
简单来说,Action 就是那个“只负责执行、不关心返回值”的委托标准件。当你需要定义一个 delegate void DoSomething(string s, int i) 时,与其从头手写,不如直接使用 Action。编译器在背后已经为你做好了所有映射,而且整个.NET基础库(比如 List 方法、Task.Run 方法)都认它,兼容性和通用性直接拉满。
- 典型应用场景:按钮的点击事件
button.Click += (s, e) => { ... },其本质就是Action的一种变体;而Task.Run(() => Console.WriteLine("done"))里用到的,正是无参数的Action。 - 注意参数上限:系统预定义的
Action最多支持16个泛型参数(从Action到Action)。一旦超过这个数量,抱歉,你就得回归老路,自己动手定义委托了。 - 给个实用建议:除非你需要多次复用同一个委托签名,并且希望给它起一个清晰易懂的名字(例如
public delegate void LogHandler(string msg);),否则,自己手写delegate纯属增加无谓的代码量。
Func 的返回值类型总在最后,这是硬规则
关于 Func,有一条铁律必须刻在脑子里:它的泛型参数列表中,最后一个类型参数,一定是返回值类型,前面的所有类型才是输入参数。这个顺序一旦搞错,编译器会毫不客气地抛出 CS0411 错误。
- 反面教材:想表达“输入一个int,返回一个string”,正确的写法是
Func。如果一不小心写成了Func,语义就完全反了,变成了“输入string,返回int”。 - 无参但有返回值:这时候就用
Func。比如,Func表示一个调用后会返回字符串的方法。这种形式在实现延迟计算时特别有用,例如:var lazyName = new Lazy。(() => GetNameFromDb()); - 一个关键限制:
Func必须要有返回值类型。所以,Func是非法语法。如果你的方法什么都不想返回,请直接去找Action。
传参时捕获变量要注意生命周期
使用lambda表达式来创建 Action 或 Func 时,如果lambda内部引用了外部的局部变量,一个经典的“闭包陷阱”可能正在等着你。比如下面这个例子:
var actions = new List(); for (int i = 0; i < 3; i++) { actions.Add(() => Console.WriteLine(i)); // 小心!这里全部会输出 3! } foreach (var a in actions) a();
- 问题根源:lambda表达式捕获的是变量
i的引用,而不是在循环每个迭代时的瞬时值。当循环结束时,i的值已经变成了3,此时所有存储在列表中的Action再去读取i,看到的自然都是这个最终值。 - 标准修复方案:在循环体内部声明一个局部变量,让lambda捕获这个“快照”。
for (int i = 0; i < 3; i++) { int localI = i; actions.Add(() => Console.WriteLine(localI)); } - 需要留意:在C# 5及更高版本中,
foreach循环的迭代变量默认已经按值捕获了,但这个“福利”并没有惠及传统的for循环,后者仍需手动处理。
话说回来,还有一个容易被忽略的高级特性——委托的协变与逆变。举个例子,Func 能直接赋值给 Func 吗?答案是不能。但反过来,Func 却可以赋值给 Func(因为string是object的子类,返回值类型支持协变)。这类细节在平常简单的委托调用中并不显眼,可一旦涉及到复杂的泛型委托转换或者框架接口设计时,它们就会突然变得至关重要。
相关攻略
C ReadOnlySpan 使用指南:高性能只读内存切片优化技巧【高级教程】 在 NET 高性能编程实践中,尤其是在字符串处理场景,一个公认的高效策略是:直接采用 ReadOnlySpan 来替代传统的 string 参数以及中间的 Substring 调用。这是目前实现零分配、低开销处理的最
SQL Server分页首选OFFSET-FETCH,需配合ORDER BY且参数化传值;EF Core用Skip Take自动翻译,避免内存分页;大数据量时应改用游标分页。 SQL Server 中用 OFFSET-FETCH 做分页最直接 说到在SQL Server里做分页,2012及以上版本提
C 万级数据批量插入:SqlBulkCopy 实战精要 在C 中进行大规模数据插入,性能是首要考量。当数据量达到万级甚至更高时,常规的逐条插入方法会迅速成为性能瓶颈。那么,有没有一种既高效又稳定的解决方案呢?答案是肯定的。 用 SqlBulkCopy 实现高速批量插入 开门见山地说,在C 生态中,
C 中使用TestContainers进行集成测试:最佳实践与常见坑点 想在 NET 里玩转 TestContainers?这事儿说简单也简单,说麻烦也麻烦。简单在于,它确实能让你用几行代码就拉起一个数据库或中间件进行测试;麻烦在于,从环境配置到代码编写,每一步都有几个“经典”的坑在等着你。今天,
C WPF Canvas画布绘图完全指南:代码动态绘制图形与连线详解 Canvas直接添加子元素导致错位或不显示的解决方案 许多C 开发者在初次使用WPF Canvas控件进行动态绘图时,常会遇到一个典型问题:为何通过代码添加的Rectangle矩形或Line线条无法正常显示,或者出现位置偏移?
热门专题
热门推荐
iPhone 17:为何成为苹果史上最长寿的爆款? 最近科技圈有个消息传得挺热:iPhone 17标准版的生产周期被大幅拉长了。这可不是简单的产能调整,背后是苹果近期完成的大规模产能扩展。看来,这款热门机型已经瞄准了今年下半年的双11战场,准备再掀一波销售热潮。 消息一出,不少网友都在猜测原因。矛头
在快节奏的都市生活中,一款兼具便携性与环保特性的出行工具正成为越来越多人的选择 城市通勤的“最后一公里”难题,催生了对灵活出行方案的持续探索。近期,小米有品推出的mini智能电动平衡车,以其独特的设计理念和深度智能化功能,迅速吸引了市场的目光。它不仅仅是一款酷玩装备,更切实地为青少年和上班族提供了高
在数字化教育蓬勃发展的当下,家长们为孩子挑选学习设备时,既希望设备具备护眼功能,又期望能满足多样化的学习需求。传统平板电脑功能虽丰富,但长时间使用易引发视力疲劳;普通学习机功能又相对单一,难以契合现代教育的发展趋势。在此背景下,科大讯飞AI学习机系列凭借先进的护眼技术与智能学习系统,成为众多家长和学
目录 ethzilla是谁? ETHZilla独特其他ETH DAT之处 1、Peter Thiel持股ETHZilla近30% 2、Vitalik和以太坊基金会入局 3、聚焦DeFi和链上策略 结语 以太坊财库概念的热度,最近真是肉眼可见。伴随着这股热潮,ETH价格也强势突破了4700美元,距离历
全球彩电市场:存量博弈下的冰与火之歌 最近,行业调研机构奥维睿沃(A VC Revo)发布了一份引人关注的报告,揭示了2025年全球彩电市场的真实图景。数据显示,全球彩电整体出货量达到2 64亿台,同比仅微跌0 1%,市场基本盘看似稳固。 然而,拆开来看,内部结构正在发生深刻变化。LCD液晶电视依然





