c#Lambda 表达式与事件核心知识点整理

一、Lambda 表达式

1. 概念 Lambda 表达式是一种匿名函数(无名称的函数),简化了委托和匿名方法的写法,格式为: (参数列表) => 表达式或语句块 它可以作为参数传递,或赋值给委托类型变量。

2. 基本语法与简写规则

形式 说明 示例
完整形式 带参数类型、大括号和 return (int a, int b) => { return a + b; }
省略参数类型 编译器自动推断参数类型 (a, b) => { return a + b; }
单参数省略括号 只有一个参数时,可省略() a => { return a * 2; }
单表达式省略大括号 函数体只有一句表达式时,省略{}return a => a * 2(自动返回结果)

3. 应用场景

  • 作为委托参数传递(如集合查询、事件处理)

  • 简化匿名方法的编写

  • 配合Func/Action等内置委托使用

示例:集合查询

复制代码
int[] numbers = { 19, 20, 3, 18, 30 };
// 查找第一个偶数(使用Lambda作为查询条件)
int firstEven = Array.Find(numbers, v => v % 2 == 0); 

4. 与托的关联 Lambda 表达式需赋值给委托类型变量(如Func/Action)才能调用:

复制代码
// Func<参数类型, 返回值类型>:带返回值的委托
Func<int, int, int> add = (a, b) => a + b;
int result = add(2, 3); // 结果:5
​
// Action<参数类型>:无返回值的委托
Action<string> print = msg => Console.WriteLine(msg);
print("Hello Lambda"); // 输出:Hello Lambda
二、事件(Event)

1. 概念 事件是一种特殊的多播委托,用于实现发布 - 订阅模式,允许对象在特定行为发生时通知其他对象。

  • 发布者:定义事件并触发它的类

  • 订阅者:注册事件并提供处理方法的类

2. 核心特性

  • 基于委托实现,通常使用EventHandlerEventHandler<TEventArgs>

  • 只能在声明它的类内部触发(调用Invoke

  • 外部只能通过+=(订阅)和-=(取消订阅)操作

  • 本质是 "安全的委托",防止外部随意修改或触发

3. 基本用法

步骤 代码示例
定义事件 public event EventHandler MyEvent;
订阅事件 MyEvent += EventHandlerMethod;(可绑定命名方法、匿名委托或 Lambda)
触发事件 MyEvent?.Invoke(sender, e);(需先检查是否有订阅者)

4. 事件处理程序的签名 必须与事件委托的签名匹配(以EventHandler为例):

复制代码
// 方法参数:事件源(sender)和事件数据(e)
void EventHandlerMethod(object sender, EventArgs e)
{
    // 处理逻辑
}

5. 多播特性 一个事件可以绑定多个处理方法,触发时按绑定顺序依次执行:

复制代码
// 绑定多个处理方法
MyEvent += Method1;
MyEvent += Method2;
MyEvent += (s, e) => Console.WriteLine("Lambda处理");
​
// 触发时依次执行Method1 → Method2 → Lambda表达式
MyEvent?.Invoke(this, EventArgs.Empty);
三、Lambda 与事件的结合使用

Lambda 表达式可简化事件处理程序的绑定:

复制代码
// 定义事件
public event EventHandler ButtonClick;
​
// 使用Lambda绑定事件处理
ButtonClick += (sender, e) => 
{
    Console.WriteLine("按钮被点击了");
};
​
// 触发事件
ButtonClick?.Invoke(this, EventArgs.Empty);

总结

  • Lambda 表达式 :简化匿名函数的编写,常用于简化委托参数,配合Func/Action使用。

  • 事件:基于委托的发布 - 订阅机制,提供安全的跨对象通信,外部只能订阅 / 取消订阅,内部触发。

  • 两者结合:使用 Lambda 可快速编写事件处理逻辑,减少代码冗余。

以下是 C# 中 Lambda 表达式的常见用法和示例表格,涵盖基本语法、场景及说明:

类型 语法格式 示例代码 说明
无参数 () => 表达式 () => Console.WriteLine("Hello") 无输入参数,执行单一表达式或语句块
单参数 参数 => 表达式 x => x * 2 单个参数可省略括号,表达式返回计算结果
多参数 (参数1, 参数2) => 表达式 (a, b) => a + b 多个参数需用括号包裹,用逗号分隔
语句块 参数 => { 语句; } n => { if (n > 0) return "正"; else return "负"; } 复杂逻辑需用{}包裹,需显式使用return返回值
委托匹配 与委托签名一致 Func<int, bool> isEven = x => x % 2 == 0; 匹配Func<int, bool>委托(输入 int,返回 bool)
事件处理 简化事件订阅 button.Click += (s, e) => Console.WriteLine("Clicked"); 替代传统的事件处理方法,简化代码
LINQ 筛选 结合Where方法 var adults = people.Where(p => p.Age >= 18); 在 LINQ 中用于定义筛选条件,p代表集合中的每个元素
LINQ 投影 结合Select方法 var names = people.Select(p => p.Name); 提取元素的特定属性,转换为新的序列
排序条件 结合OrderBy方法 var sorted = numbers.OrderBy(n => n); 定义排序依据,此处按元素本身升序排序
匿名类型创建 生成匿名对象 people.Select(p => new { p.Name, AgeGroup = p.Age / 10 * 10 }) 在 LINQ 中创建匿名类型,包含指定字段(如NameAgeGroup
闭包捕获变量 访问外部变量 int threshold = 10; var filtered = list.Where(x => x > threshold); 可访问 Lambda 表达式外部的变量(threshold),形成闭包
异步 Lambda 结合async/await async () => await HttpClient.GetAsync("https://example.com") async修饰,内部可使用await,返回TaskTask<T>

关键特性说明:

  1. 简洁性 :相比匿名方法,语法更简洁,省略了delegate关键字和参数类型(编译器自动推断)。

  2. 类型推断:参数类型通常可省略,编译器会根据上下文(如委托类型、LINQ 方法)自动推断。

  3. 不可变性 :Lambda 表达式本身是匿名函数,无法直接调用,需赋值给委托类型(如FuncAction)或作为方法参数传递。

  4. 闭包特性:能捕获并访问外部作用域的变量,变量的生命周期会被延长至 Lambda 表达式使用完毕。

  5. 适用场景:主要用于简化委托调用、事件处理、LINQ 查询、异步操作等场景,减少代码冗余。

相关推荐
钟离墨笺几秒前
Go 语言-->指针
开发语言·后端·golang
时光追逐者17 分钟前
C#/.NET/.NET Core技术前沿周刊 | 第 48 期(2025年7.21-7.27)
c#·.net·.netcore·.net core
前端梭哈攻城狮20 分钟前
dify二开示例
前端·后端·python
蓝点lilac21 分钟前
C# 调用邮箱应用发送带附件的邮件
c#·.net
秋难降23 分钟前
一篇文章带你了解Pandassssssssssssssss
大数据·python·pandas
java1234_小锋26 分钟前
[免费]【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts)【论文+源码+SQL脚本】
python·flask·nlp·舆情分析·微博舆情分析
weixin_贾31 分钟前
模块自由拼装!Python重构DSSAT作物模块教程(以杂交水稻为例)
python·dssat
超浪的晨31 分钟前
Java 代理机制详解:从静态代理到动态代理,彻底掌握代理模式的原理与实战
java·开发语言·后端·学习·代理模式·个人开发
咖啡の猫42 分钟前
bash的特性-bash中的引号
开发语言·chrome·bash
java叶新东老师1 小时前
idea提交时忽略.class、.iml文件和文件夹或目录的方法
java·开发语言