lambda表达式
Lambda 表达式是一种可用于创建 委托 或 表达式目录树 类型的 匿名函数 。
通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地函数。
一般用于编写LINQ查询表达式
将表达式分配给委托类型
1 | delegate int del(int i); |
创建表达式目录树类型
1 | using System.Linq.Expressions' |
=> 运算符
=> 标记称作 lambda 运算符。 该标记在 Lambda 表达式中用来将左侧的输入变量与右侧的 lambda 体分离。
Lambda 表达式是类似于匿名方法的内联表达式,但更加灵活;在以方法语法表示的 LINQ 查询中广泛使用了 Lambda 表达式。
=>运算符具有跟赋值运算符相同的优先级并且是右结合运算
表达式lambda
1 | 基本形式 |
语句lambda
语句 lambda 与表达式 lambda 表达式类似,只是语句括在大括号中:1
2
3
4
5
6
7
8
9(input-parameters) => { statement; }
delegate void TestDelegate(string s);
TestDelegate del = n => {
string s = n + "World";
//...
}
异步lambda
通过使用 async 和 await 关键字,你可以轻松创建包含异步处理的 lambda 表达式和语句。
例如,下面的 Windows 窗体示例包含一个调用和等待异步方法 ExampleMethodAsync的事件处理程序。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
// ExampleMethodAsync returns a Task.
await ExampleMethodAsync();
textBox1.Text += "\r\nControl returned to Click event handler.\n";
}
async Task ExampleMethodAsync()
{
// The following line simulates a task-returning asynchronous process.
await Task.Delay(1000);
}
}
//更改之后
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
button1.Click += async (sender, e) =>
{
// ExampleMethodAsync returns a Task.
await ExampleMethodAsync();
textBox1.Text += "\nControl returned to Click event handler.\n";
};
}
async Task ExampleMethodAsync()
{
// The following line simulates a task-returning asynchronous process.
await Task.Delay(1000);
}
}
带有标准查询运算符的lambda
许多标准查询运算符都具有输入参数,其类型是泛型委托系列 Func<T,TResult> 中的一种。 这些委托使用类型参数来定义输入参数的数量和类型,以及委托的返回类型。
Func 委托对于封装用户定义的表达式非常有用,这些表达式将应用于一组源数据中的每个元素。1
2
3
4
5
6
7
8
9
10
11public delegate TResult Func<TArg0, TResult>(TArg0, arg0)
Func<int, bool> myFunc = x => x == 5;
bool result = myFunc(4); // returns false of course
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);
var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);
var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index);
lambda中的类型推理
在编写 lambda 时,通常不必为输入参数指定类型,因为编译器可以根据 lambda 主体、参数的委托类型以及 C# 语言规范中描述的其他因素来推断类型。 对于大多数标准查询运算符,第一个输入是源序列中的元素类型。
lambda 的一般规则
- Lambda 包含的参数数量必须与委托类型包含的参数数量相同。
- Lambda 中的每个输入参数必须都能够隐式转换为其对应的委托参数。
- Lambda 的返回值(如果有)必须能够隐式转换为委托的返回类型。
1
customers.Where(c => c.City == "London");