zl程序教程

您现在的位置是:首页 >  其它

当前栏目

Lambda表达式表达式树

表达式 lambda
2023-09-14 09:04:36 时间
在C#3.0中,继匿名方法之后出现了Lambda 表达式,使表达更为简洁、快捷。Lambda 表达式使用Lambda 运算符 “= ”来定义,语法如下: (参数列表) = {方法体} Lambda 运算符的左边是输入参数,定义Lambda表达式的接收参数列表,右边包含表达式或语句块,表示将表达式的值或语句块返回的值传给左边的参数列表。 Lambda 表达式是一个匿名函数,可以包

=  运算符具有与赋值运算符 (=) 相同的优先级并且是右结合运算(参见“运算符”文章的“结合性”部分)。

Lambda 在基于方法的 LINQ 查询中用作标准查询运算符方法(如 Where``1)的参数。

使用基于方法的语法在 Enumerable 类中调用 Where``1 方法时(如在 LINQ to Objects 和 LINQ to XML 中一样),参数是委托类型 Func。 使用 Lambda 表达式创建该委托最为方便。 例如,当你在 Queryable 类中调用相同的方法时(如在 LINQ to SQL 中一样),参数类型为 Expression Func ,其中 Func 是最多具有十六个输入参数的任何一个 Func 委托。 同样,Lambda 表达式只是一种非常简洁的构造该表达式目录树的方式。 尽管事实上通过 Lambda 创建的对象具有不同的类型,但 Lambda 使得 Where 调用看起来类似。

在上一个示例中,请注意委托签名具有一个 int 类型的隐式类型输入参数,并返回 int。 可以将 Lambda 表达式转换为该类型的委托,因为该表达式也具有一个输入参数 (x),以及一个编译器可隐式转换为 int 类型的返回值。(以下几节中将对类型推理进行详细讨论。)使用输入参数 5 调用委托时,它将返回结果 25。

在 is 或 as 运算符的左侧不允许使用 Lambda。

适用于匿名方法的所有限制也适用于 Lambda 表达式。 有关更多信息,请参见匿名方法(C# 编程指南)


表达式位于 = 运算符右侧的 lambda 表达式称为“表达式 lambda”。 表达式 lambda 广泛用于表达式树(C# 和 Visual Basic)的构造。 表达式 lambda 会返回表达式的结果,并采用以下基本形式:


仅当 lambda 只有一个输入参数时,括号才是可选的;否则括号是必需的。 括号内的两个或更多输入参数使用逗号加以分隔:

C#

在上一个示例中,请注意表达式 Lambda 的主体可以包含一个方法调用。 但是,如果要创建在 .NET Framework 之外计算的表达式目录树(例如,在 SQL Server 中),则不应在 lambda 表达式中使用方法调用。 在 .NET 公共语言运行时上下文之外,方法将没有任何意义。


TestDelegate myDel = n = { string s = n + " " + "World"; Console.WriteLine(s); }; myDel("Hello");
await ExampleMethodAsync(); textBox1.Text += "\r\nControl returned to Click event handler.\r\n"; async Task ExampleMethodAsync() // The following line simulates a task-returning asynchronous process. await Task.Delay(1000);

你可以使用异步 lambda 添加同一事件处理程序。 若要添加此处理程序,请在 lambda 参数列表前添加一个 async 修饰符,如下例所示。

C#
await ExampleMethodAsync(); textBox1.Text += "\r\nControl returned to Click event handler.\r\n"; async Task ExampleMethodAsync() // The following line simulates a task-returning asynchronous process. await Task.Delay(1000);

可以将委托实例化为 Func int,bool myFunc,其中 int 是输入参数,bool 是返回值。 返回值始终在最后一个类型参数中指定。 Func int, string, bool  定义包含两个输入参数(int 和 string)且返回类型为 bool 的委托。 当调用下面的 Func 委托时,该委托将返回 true 或 false 以指示输入参数是否等于 5:

C#
Func int, bool myFunc = x = x == 5;

bool result = myFunc(4); // returns false of course


当参数类型为 Expression Func  时,你也可以提供 Lambda 表达式,例如在 System.Linq.Queryable 内定义的标准查询运算符中。 如果指定 Expression Func  参数,lambda 将编译为表达式目录树。

此处显示了一个标准查询运算符,Count``1 方法:

C#
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

int oddNumbers = numbers.Count(n = n % 2 == 1);


编译器可以推断输入参数的类型,或者你也可以显式指定该类型。 这个特殊 lambda 表达式将计算那些除以 2 时余数为 1 的整数的数量 (n)。

下面一行代码将生成一个序列,其中包含 numbers 数组中在 9 左侧的所有元素,因为它是序列中第一个不满足条件的数字:

C#

此示例展示了如何通过将输入参数括在括号中来指定多个输入参数。 该方法将返回数字数组中的所有元素,直至遇到一个值小于其位置的数字为止。 不要将 lambda 运算符 (= ) 与大于等于运算符 ( =) 混淆。

C#

在编写 lambda 时,通常不必为输入参数指定类型,因为编译器可以根据 lambda 主体、参数的委托类型以及 C# 语言规范中描述的其他因素来推断类型。 对于大多数标准查询运算符,第一个输入是源序列中的元素类型。 因此,如果要查询 IEnumerable Customer ,则输入变量将被推断为 Customer 对象,这意味着你可以访问其方法和属性:

C#

Lambda 包含的参数数量必须与委托类型包含的参数数量相同。

Lambda 中的每个输入参数必须都能够隐式转换为其对应的委托参数。

Lambda 的返回值(如果有)必须能够隐式转换为委托的返回类型。

请注意,lambda 表达式本身没有类型,因为常规类型系统没有“Lambda 表达式”这一内部概念。但是,有时以一种非正式的方式谈论 lambda 表达式的“类型”会很方便。 在这些情况下,类型是指委托类型或 lambda 表达式所转换到的 Expression 类型。


// Initialize the delegates with lambda expressions. // Note access to 2 outer variables. // del will be invoked within this method. del = () = { j = 10; return j input; }; // del2 will be invoked after TestMethod goes out of scope. del2 = (x) = {return x == j; }; // Demonstrate value of j: // Output: j = 0 // The delegate has not been invoked yet. Console.WriteLine("j = {0}", j); // Invoke the delegate. bool boolResult = del(); // Output: j = 10 b = True Console.WriteLine("j = {0}. b = {1}", j, boolResult); static void Main() Test test = new Test(); test.TestMethod(5); // Prove that del2 still has a copy of // local variable j from TestMethod. bool result = test.del2(10); // Output: True Console.WriteLine(result); Console.ReadKey();

捕获的变量将不会被作为垃圾回收,直至引用变量的委托符合垃圾回收的条件。

在外部方法中看不到 lambda 表达式内引入的变量。

Lambda 表达式无法从封闭方法中直接捕获 ref 或 out 参数。

Lambda 表达式中的返回语句不会导致封闭方法返回。

如果跳转语句的目标在块外部,则 lambda 表达式不能包含位于 lambda 函数内部的 goto 语句、break 语句或 continue 语句。 同样,如果目标在块内部,则在 lambda 函数块外部使用跳转语句也是错误的。


C++中的Lambda表达式 在 `C++11` 及之后的版本中,`C++` 提供了 `lambda` 表达式,它是一种方便了参数传递和定义匿名函数的方法。该方法通常用于封装算法、执行异步方法 ,也就是说比较适用于少量的代码。
大话lambda表达式 大话lambda表达式 LAMBDA表达式Lambda是一个表达式,也可以说它是一个匿名函数。然而在使用它或是阅读Lambda代码的时候,却显得并不那么容易。因为它匿名,因为它删减了一些必要的说明信息(比如方法名)。
3分钟理解Lambda表达式 原文:3分钟理解Lambda表达式 1.什么是Lambda表达式 Lambda表达式是一个匿名方法,通常在LINQ中被用来创建委托 简单来说。它是一个没有声明,没有访问修饰符,没有返回值。甚至没有名字的方法。
本文提供全流程,中文翻译。 Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例)
2、map:如果一个函数可以将一种类型的值转换成另一种类型,map操作就可以使用该函数,将一个流中的值转换成一个新的流