news 2026/7/23 2:42:31

C#委托、事件和lambda表达式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C#委托、事件和lambda表达式

委托

委托就像是方法的类型,有了委托就可以把方法当参数传来传去,或者在一个变量里随时换掉要执行的方法。

// 1. 声明一个委托类型(定义:我能代表哪种方法) public delegate void MyDelegate(string msg); // 2. 写一个符合签名的方法 public static void ShowMessage(string text) { Console.WriteLine($"消息:{text}"); } // 3. 使用 MyDelegate del = ShowMessage; // 把方法赋值给委托变量 del("Hello"); // 调用委托,相当于调用 ShowMessage

大多数情况下不需要自己声明委托,直接用系统自带的就行。

// Action 示例(无返回值) Action<string> print = s => Console.WriteLine(s); print("直接用 Action"); // Func 示例(有返回值) Func<int, int, int> add = (a, b) => a + b; int result = add(3, 4); // 7

委托可以串联多个方法,调用一次就会按顺序执行全部,也就是多播。

Action act = MethodA; act += MethodB; act += MethodC; act(); // 依次执行 A、B、C // 移除方法 act -= MethodB;

事件

事件就是加了限制的委托,比如只能从外部“订阅”和“取消订阅”,不能直接触发或覆盖。相当于给委托封装了一下。

下面举个例子:

// 定义一个事件发布者 public class Button { // 事件:外部可以订阅,但不能随意触发 public event EventHandler? Clicked; // 模拟点击按钮 public void Click() { Console.WriteLine("按钮被点击了"); // 触发事件(只能在类内部触发) Clicked?.Invoke(this, EventArgs.Empty); } } // 使用 class Program { static void Main() { Button btn = new Button(); // 订阅事件(用 +=) btn.Clicked += OnButtonClicked; // 触发点击 btn.Click(); // 取消订阅(用 -=) btn.Clicked -= OnButtonClicked; // btn.Clicked.Invoke(null, null); ❌ 编译错误,外部不能触发 // btn.Clicked = null; ❌ 编译错误,外部不能赋值 } static void OnButtonClicked(object? sender, EventArgs e) { Console.WriteLine("事件处理:按钮被点击了!"); } }

输出是:

按钮被点击了 事件处理:按钮被点击了!

在.NET中推荐是使用EventHandler和EventHandler<T>,它有两个参数:

public event EventHandler<CustomEventArgs>? DataReceived;

标准写法是:

public class DataProcessor { // 声明事件(使用标准 EventHandler<T>) public event EventHandler<ProcessCompletedEventArgs>? ProcessCompleted; public void StartProcess() { // 模拟处理 Console.WriteLine("处理中..."); Thread.Sleep(1000); // 处理完成,触发事件 OnProcessCompleted(10); // 假设处理了10条数据 } // 受保护的触发方法(约定:On + 事件名) protected virtual void OnProcessCompleted(int count) { ProcessCompleted?.Invoke(this, new ProcessCompletedEventArgs(count)); } } // 自定义事件参数类 public class ProcessCompletedEventArgs : EventArgs { public int RecordCount { get; } public ProcessCompletedEventArgs(int count) => RecordCount = count; } // 使用 class Program { static void Main() { var processor = new DataProcessor(); processor.ProcessCompleted += (sender, e) => { Console.WriteLine($"处理完成!共 {e.RecordCount} 条数据"); }; processor.StartProcess(); } }

Lambda表达式

lambda表达式就是匿名方法的简写,是C#中最常用最实用的特性之一。

传统写法:

// 定义方法 bool IsEven(int x) { return x % 2 == 0; } // 使用 List<int> numbers = new List<int>{1,2,3,4,5}; var evens = numbers.Where(IsEven);

lambda写法:

var evens = numbers.Where(x => x % 2 == 0);

最直观的看到lambda写法少写了三行代码,显著减少了代码冗余。

lambda可以捕获外部变量,也就是闭包:

int multiplier = 3; Func<int, int> multiply = x => x * multiplier; // 捕获了 multiplier int result = multiply(5); // 15 multiplier = 10; result = multiply(5); // 50(外部变量变化,Lambda 也跟着变)

但在循环中捕获变量时,很容易造成“延迟执行”的问题。

var actions = new List<Action>(); for (int i = 0; i < 3; i++) { actions.Add(() => Console.WriteLine(i)); // 捕获同一个 i } foreach (var action in actions) { action(); // 输出 3, 3, 3 而不是 0,1,2 }

解决方法也很简单,就是在循环内局部复制一份:

for (int i = 0; i < 3; i++) { int copy = i; // 每次循环新建一个变量 actions.Add(() => Console.WriteLine(copy)); } // 输出 0,1,2

一般情况下,编译器会根据上下文推断lambda的类型,只有上下文不够明确时,才需要显示声明类型:

// ❌ 错误:无法推断 var lambda = x => x * 2; // ✅ 正确:明确委托类型 Func<int, int> lambda = x => x * 2;
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/23 2:42:09

真激动,千问新人优惠券大放送!激活码:千问新人福利yPBm3m

最近整理了通义千问新用户得福利的小技巧&#xff0c;把最新的信息分享给大家&#xff1a;操作步骤先在手机应用商店找到千问APP&#xff0c;用之前没用过它的手机号注册登录&#xff1b;跟着APP里的指引绑定支付宝账号&#xff0c;这一步是拿到福利和抵扣的必要环节&#xff1…

作者头像 李华
网站建设 2026/7/23 2:41:11

如果f(3x+2)是奇函数,求f(x)的对称中心

如果 f(3x2) 是奇函数&#xff0c;那么 f(x) 关于点 (2, 0) 对称。 推导过程&#xff1a; 奇函数定义&#xff1a;令 ( g(x) f(3x2) )&#xff0c;则 ( g(-x) -g(x) )。代入得&#xff1a; ( f(-3x2) -f(3x2) )。换元&#xff1a;令 ( t 3x2 )&#xff0c;则 ( -3x2 4 - t…

作者头像 李华
网站建设 2026/7/23 2:40:36

ESP32网络电台DIY:低成本构建物联网音频系统

1. ESP32网络电台项目概述在物联网和嵌入式系统领域&#xff0c;ESP32无疑是一颗耀眼的明星。这款售价仅7美元左右的开发板&#xff0c;集成了双核32位处理器、Wi-Fi、蓝牙等丰富功能&#xff0c;使其成为DIY项目的理想选择。今天我们要实现的&#xff0c;就是利用ESP32构建一个…

作者头像 李华
网站建设 2026/7/23 2:40:27

2026年AI大模型岗位趋势与核心技术解析

1. 2026年AI岗位市场全景分析2026年的大模型技术岗位已经成为科技行业最炙手可热的高薪赛道。根据最新行业调研数据显示&#xff0c;大模型相关岗位数量同比暴增12倍&#xff0c;人才供需比低至1:10&#xff0c;全行业人才缺口超500万。一线城市大模型开发工程师平均薪资已达22…

作者头像 李华
网站建设 2026/7/23 2:40:16

Loop Engineering 学习笔记:从手写 Prompt 到设计循环

为什么有这篇 最近我在看 Agent Loop 和 Loop Engineering。 一开始我以为它只是“让 AI 多跑几轮”。但看了一些实践和讨论后&#xff0c;我的理解变了&#xff1a;Loop 不是多调用几次模型&#xff0c;而是把 Agent 的工作方式从“人一步步提示”&#xff0c;变成“系统自己…

作者头像 李华
网站建设 2026/7/23 2:39:19

多语言句子嵌入与可靠性审计:技术原理与部署实践

这次我们来看一个结合多语言句子嵌入与语言集成可靠性审计的技术项目。这个标题指向的是利用多语言文本表示技术来增强审计过程的可靠性分析能力&#xff0c;特别适合需要处理多语言文档质量评估、合规检查或内容审核的场景。从技术架构来看&#xff0c;这个项目核心是多语言句…

作者头像 李华