C#中的Lambda表达式是一种简洁的匿名函数表示方式,它可以用来简化委托、事件、LINQ查询等场景下的代码编写,让原本需要多行定义的匿名函数可以用更紧凑的语法实现。它本质上是匿名函数的语法糖,在编译后会生成对应的委托实例或者表达式树,具备和普通方法相同的执行逻辑。

Lambda表达式的基本语法
Lambda表达式的核心结构是参数列表加上=>运算符,后面跟着表达式或者语句块,基本格式如下:
// 语法格式:(参数列表) => 表达式 或 语句块
// 无参数情况
() => 表达式
// 单个参数,可省略括号
参数 => 表达式
// 多个参数
(参数1, 参数2) => 表达式
// 带语句块的情况
(参数1, 参数2) => {
语句1;
语句2;
return 结果;
}
当Lambda表达式只有一行返回语句时,可以省略return关键字和大括号,编译器会自动推断返回结果。如果有多行逻辑,则需要用大括号包裹,并且显式写return返回结果。
Lambda表达式与委托的关联
Lambda表达式最常见的用途是给委托赋值,C#内置了很多常用的委托类型,比如Action、Func,可以直接用Lambda表达式初始化:
using System;
class Program
{
static void Main()
{
// Action是无返回值的委托,这里用Lambda表达式定义无参无返回值的委托实例
Action printHello = () => Console.WriteLine("Hello Lambda");
printHello(); // 输出 Hello Lambda
// Func是有返回值的委托,最后一个泛型参数是返回值类型
// 这里定义接收两个int参数返回int的委托
Func<int, int, int> add = (a, b) => a + b;
int result = add(3, 5);
Console.WriteLine(result); // 输出 8
// 带语句块的Lambda表达式
Func<int, int> square = x => {
int temp = x * x;
return temp;
};
Console.WriteLine(square(4)); // 输出 16
}
}
Lambda表达式的常见应用场景
1. LINQ查询中的使用
Lambda表达式是LINQ查询的核心组成部分,很多LINQ扩展方法都接收委托参数,用Lambda表达式可以非常简洁地实现数据筛选、排序、投影等操作:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8 };
// 筛选偶数
var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();
Console.WriteLine("偶数:" + string.Join(",", evenNumbers)); // 输出 2,4,6,8
// 排序,按数字倒序
var sortedNumbers = numbers.OrderByDescending(n => n).ToList();
Console.WriteLine("倒序:" + string.Join(",", sortedNumbers)); // 输出 8,7,6,5,4,3,2,1
// 投影,把每个数字乘2
var doubledNumbers = numbers.Select(n => n * 2).ToList();
Console.WriteLine("乘2后:" + string.Join(",", doubledNumbers)); // 输出 2,4,6,8,10,12,14,16
}
}
2. 事件处理中的使用
在给事件注册处理方法时,也可以用Lambda表达式简化代码,不需要单独定义事件处理方法:
using System;
using System.Timers;
class Program
{
static void Main()
{
Timer timer = new Timer(1000); // 1秒触发一次
// 用Lambda表达式注册Elapsed事件的处理逻辑
timer.Elapsed += (sender, e) => Console.WriteLine($"定时器触发,时间:{e.SignalTime}");
timer.Start();
Console.ReadLine(); // 保持程序运行
}
}
3. 作为方法参数传递
如果方法的参数是委托类型,也可以直接传递Lambda表达式,让代码更紧凑:
using System;
class Program
{
// 定义一个接收Func委托参数的方法
static void Calculate(Func<int, int, int> operation, int a, int b)
{
int result = operation(a, b);
Console.WriteLine($"计算结果:{result}");
}
static void Main()
{
// 传递Lambda表达式作为方法参数
Calculate((x, y) => x + y, 10, 20); // 输出 计算结果:30
Calculate((x, y) => x * y, 10, 20); // 输出 计算结果:200
}
}
Lambda表达式的注意事项
- Lambda表达式的参数类型可以省略,编译器会根据委托类型自动推断,但是如果无法推断时,需要显式指定参数类型,比如
(int x, int y) => x + y。 - 如果Lambda表达式捕获了外部变量,那么这个变量会被闭包持有,即使外部变量的作用域已经结束,只要委托实例还存在,该变量就不会被回收。
- Lambda表达式不能单独存在,必须赋值给委托类型、表达式树类型,或者作为方法参数传递,不能直接调用。
- 当Lambda表达式的语句块中有多条语句时,必须显式写
return返回结果,否则委托的返回值会不符合预期。
Lambda表达式是C#函数式编程特性的重要体现,合理使用它可以大幅减少冗余代码,让逻辑更清晰。但也不要过度使用,在逻辑复杂的情况下,单独定义方法会让代码可读性更高。