在 C# 中,Lambda 表达式是一种简洁的语法,用于创建匿名函数。它可以作为参数传递给方法,或用于定义委托类型的变量。Lambda 表达式在 LINQ 查询、事件处理和异步编程中广泛使用。
1. 基本语法
Lambda 表达式使用 =>
(称为 Lambda 运算符)分隔参数和表达式主体。
无参数
() => Console.WriteLine("Hello, Lambda!");
单个参数
x => x * x; // 等价于:int Square(int x) { return x * x; }
多个参数
(x, y) => x + y; // 加法运算
显式参数类型
(int x, int y) => x * y; // 乘法运算
2. Lambda 表达式的主体
表达式体
如果 Lambda 只包含一个表达式,可以省略 return
语句。
x => x.Length; // 返回字符串长度
语句体
如果 Lambda 包含多个语句,需要用大括号 {}
包裹,并显式使用 return
。
x => {
Console.WriteLine($"Processing: {x}");
return x * x;
};
3. 捕获外部变量
Lambda 可以捕获其定义所在作用域中的变量。
int multiplier = 10;
Func<int, int> multiply = x => x * multiplier; // 捕获 multiplier 变量
Console.WriteLine(multiply(5)); // 输出 50
4. 在 LINQ 查询中的应用
Lambda 表达式是 LINQ 的核心,用于筛选、投影和排序数据。
筛选数据(Where)
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(n => n % 2 == 0); // [2, 4]
投影数据(Select)
var squared = numbers.Select(n => n * n); // [1, 4, 9, 16, 25]
排序(OrderBy)
var sorted = numbers.OrderBy(n => n); // 升序排序
5. 作为委托类型使用
Lambda 表达式可以赋值给委托类型的变量。
使用 Func<> 委托
Func<int, int, int> add = (x, y) => x + y;
int result = add(3, 5); // 结果:8
使用 Action<> 委托(无返回值)
Action<string> print = message => Console.WriteLine(message);
print("Hello, Lambda!");
6. 异步 Lambda
使用 async
关键字创建异步 Lambda 表达式。
Func<Task<int>> asyncLambda = async () => {
await Task.Delay(1000);
return 42;
};
await asyncLambda(); // 异步执行
7. 与表达式树结合
Lambda 表达式可以转换为表达式树(Expression<Func<>>
),用于动态查询。
Expression<Func<int, bool>> expression = n => n > 5;
// 表达式树可以被编译或分析
8. 示例:组合使用 Lambda
List<Person> people = new List<Person> {
new Person { Name = "Alice", Age = 30 },
new Person { Name = "Bob", Age = 25 },
new Person { Name = "Charlie", Age = 35 }
};
// 查询年龄大于30的人,并按姓名排序
var result = people
.Where(p => p.Age > 30)
.OrderBy(p => p.Name)
.Select(p => p.Name);
// 结果:["Charlie"]
Lambda 与匿名方法的区别
Lambda 表达式是匿名方法的语法糖,更简洁且支持表达式树。例如:
// 匿名方法
delegate(int x) { return x * x; }
// Lambda 表达式(更简洁)
x => x * x
注意事项
-
捕获变量的生命周期:Lambda 捕获的变量在 Lambda 执行时才求值,可能导致意外结果。
-
性能:表达式树的编译开销较大,避免在高性能场景中频繁使用。
-
类型推断:编译器会自动推断 Lambda 参数的类型,但在复杂场景中可能需要显式指定。
Lambda 表达式是 C# 中强大且灵活的特性,能够显著简化代码并提高可读性。