先看一个例子:
-
Expression<Func<
string
,
bool
>> expr = o => o.Length > 10;
初次接触Lambda表达式的人可能会被搞迷糊,这样的语句到底是什么意思,怎么样工作,原理又是什么。
逐级分析以上语句,分为两个部分,以等号为界。
第一部分是变量类型的申明:Expression<Func<string, bool>>
expr,表示expr这个变量是一个Lambda表达式,这个表达式符合这样的一种委托:bool DelegateName(string
obj)。
第二部分是表达式的声明o => o.Length >
10
,这个“=>”是Lambda操作符,读作“转到”,必须把=>左右看成是一个整体,因为这实际是一个匿名方法,“=>”左边是方
法传入参数的申明,右边是函数体,如果用常规的表示方法,可以写成如下形式:
-
bool
MethodName(
string
o)
-
{
-
return
o.Length > 10;
-
}
仔细观察两部分拆解以后的形式其实不难发现,第一部分的工作是定义了一个匿名的委托,而第二部分则是符合这个匿名委托的一个方法,由于这个方法没有明确给定名称,因此称为匿名方法。
那么,expr到底又是什么样的东西。有一点必须明确的是,expr表示绝对不是这个匿名方法的返回值,而是这个匿名方法中所有表达式的
System.Linq.Expressions.Expression形式。也就是说,在expr中,这个函数体里所有的表达式已经被拆解成一个一个的
单元,每一个单元都是一种System.Linq.Expressions.Expression的派生类。由于表达式和表达式之前存在着上下级的关系,
因此所有的表达式呈现一种树状结构,称为表达式树。
一个匿名方法是如何转换为表达式树的呢?这个问题其实不用太过关心,因为C#编译器在对程序编译的时候已经将上述第二部分的内容自动转换为相应的表达式树了。上述例子中编译的结果通过Reflector反编译出来的内容如下所示:
-
ParameterExpression CS$0$0000;
-
Expression<Func<
string
,
bool
>> expr = Expression.Lambda<Func<
string
,
bool
>>(Expression.GreaterThan(Expression.Property(CS$0$0000 = Expression.Parameter(
typeof
(
string
),
"o"
), (MethodInfo) methodof(
string
.get_Length)), Expression.Constant(10,
typeof
(
int
))),
new
ParameterExpression[] { CS$0$0000 });
-
这串代码看起来有点糊,我把代码梳理了一下使得它更容易读,如下所示:
-
Expression<Func<
string
,
bool
>> expr;
-
-
-
ParameterExpression paramExpr = Expression.Parameter(
typeof
(
string
),
"o"
);
-
-
PropertyInfo propInfo =
typeof
(
string
).GetProperty(
"Length"
, BindingFlags.Instance | BindingFlags.Public);
-
-
MemberExpression memberExpr = Expression.Property(paramExpr, propInfo);
-
-
ConstantExpression constExpr = Expression.Constant(10,
typeof
(
int
));
-
-
BinaryExpression greaterThanExpr = Expression.GreaterThan(memberExpr, constExpr);
-
-
expr = Expression.Lambda<Func<
string
,
bool
>>(greaterThanExpr, paramExpr);
-
是不是好麻烦啊?呵呵,好在这些工作已经在编译的时候完成了,不需要我们手工创建,除非你想动态创建表达式。关于如何动态创建表达式,我在这里就先不详细说明了,将在下一博里再详述。
综上所述,对待Lambda表达式,最基本一个原则是不要把表达式看成了语句的运算结果,而应该看成这些语句本身,也就是把语句作为对象来处理。语句和语句之间通过表达式树来关联,而从语句转换为表达式树已由编译器自动完成,不需要人工介入。
在下一篇文章中,我将会对表达式树和语句的对应关系,以及如何动态构造表达式进行一些说明,敬请期待。
分享到:
相关推荐
- **表达式Lambda**:如果Lambda主体是单一表达式,如`x => x * x`,它会返回表达式的结果。 - **语句Lambda**:如果Lambda主体包含一个或多个语句,需要用大括号包围,如`(n) => { Console.WriteLine(n); }`。...
Lambda表达式的基本形式可以表示为`(参数列表) => 表达式`或`(参数列表) => { 函数体 }`。在SqlLink中,开发者可以通过Lambda表达式定义查询条件,比如查找年龄大于30岁的用户: ```csharp var sql = SqlLink....
【Java8】Lambda表达式 和 Stream API 是Java编程语言中的两个重要创新,它们极大地提升了代码的简洁性和可读性,特别是在处理集合数据时。这里我们将深入探讨这两个特性,并结合实际示例来理解它们的工作原理。 ...
Lambda表达式是C#中的一种简洁的匿名函数表示方式,它的语法形式为`(参数) => 表达式`。在EF中,Lambda表达式常用于构建 LINQ (Language Integrated Query) 查询,这些查询直接在对象层进行,然后由EF转换为相应的...
所有的 Lambda 表达式都使用操作符“=>“,表示“goes to (转变为)”。 Lambda 表达式简介 Lambda 表达式是一个包含若干表达式和语句的匿名函数。可以被用作创建委托对象或表达式树类型。所有的 Lambda 表达式都...
在上面的示例中,`n => n % 2 == 0`是一个Lambda表达式,它作为`Where`方法的参数,用于判断数字是否为偶数。 Lambda表达式还可以有零个、一个或多个输入参数,参数之间用逗号分隔,如果参数类型可以推断,可以不写...
《精通Lambda表达式:Java多核编程》
Lambda表达式的语法结构简洁明了,通常由"lambda运算符" => 分割两部分,左边是输入参数(如果有的话),右边是表达式或语句块。 1. **Lambda表达式的基本形式** Lambda表达式的基本形式可以分为两种:表达式...
2. `async`方法:lambda表达式可以用于定义`async`方法,如`(int id) => Task.FromResult(GetData(id))`,这是一个接收整型参数并返回异步结果的lambda表达式。 五、事件处理与lambda表达式 1. 在事件处理中,...
var evenNumbers = numbers.Where(n => n % 2 == 0).Select(n => n * 2); foreach (var num in evenNumbers) { Console.WriteLine(num); } ``` 这段代码将筛选出偶数并将其乘以2。 ### 5. Lambda表达式的参数 ...
例如 `(int x, int y) => x + y` 是一个接受两个整数参数并返回它们之和的lambda表达式。 "匿名方法"与Lambda表达式类似,但不使用lambda操作符。它是在没有定义名称的情况下创建的方法,通常作为参数传递给其他...
3. 匿名方法中,"("、")"内是方法的参数的集合,这就对应了 Lambda 表达式中的"(参数列表)",而匿名方法中"{"、"}"内是方法的语句块,这对应了 Lambda 表达式中"=>"符号右边的表达式或语句块项。 Lambda 表达式的...
var col2 = Orders.Where(o => o.CustomerID == 84); ``` 这两个表达式都会返回CustomerID等于84的所有订单。 ### **返回匿名类型(Return Anonymous Type)** 当你需要创建一个新的对象类型,但又不想显式定义一个...
编程选择题40道:Java 8新特性:Lambda表达式与Stream API.Tex.docx
所有 Lambda 表达式都使用 Lambda 运算符 => ,该运算符读为 “ goes to ”。该 Lambda 运算符的左边是输入参数(如果有),右边包含表达式或语句块。 Lambda 表达式的优点: * 可以创建委托类型 * 可以创建...
分析:上述Lambda表达式的输入参数省略了一对小括弧,它与“(m)=>m*2” Lambda表达式是等效的。 示例 3:两个输入参数的Lambda表达式 [csharp]view plaincopy 1. (m,n)=>m*n; 二、表达式或语句块 Lambda表达式的...
其中,“参数列表”定义了传递给Lambda表达式的参数,“=>”符号表示Lambda运算符,“表达式”或“语句块”则定义了Lambda表达式的行为逻辑。 - **多参数Lambda表达式**:当需要多个参数时,这些参数可以通过逗号...
Lambda表达式则可以让我们直接在一行代码内完成这个过程,例如 `(a, b) -> a.compareTo(b)`。 在Android开发中,Lambda表达式尤其适用于事件监听、数据处理和异步操作。例如,我们可以在点击事件处理中使用Lambda,...
例如, Lambda 表达式 x => x * x 读作"x goes to x times x"。 Lambda表达式的应用场景 ------------------------- Lambda表达式广泛应用于各种领域,例如数据处理、排序、筛选等。它可以帮助开发者快速地实现...