表达式 lambda 和语句 lambda 的区别

Posted

技术标签:

【中文标题】表达式 lambda 和语句 lambda 的区别【英文标题】:Difference between expression lambda and statement lambda 【发布时间】:2013-06-21 17:01:02 【问题描述】:

表达式 lambda 和语句 lambda 有区别吗?

如果有,有什么区别?

在下面的链接中找到了这个问题,但无法理解答案 什么是表达式 Lambda?

C# interview Questions

该链接中提到的答案是这样的 右侧有表达式的 lambda 表达式称为表达式 lambda。

根据我的理解,表达式始终仅在右侧。这就是我问这个问题的原因。有什么我不知道的吗?

【问题讨论】:

您遇到这两个术语的来源将帮助我们解释差异(如果有)。 你的意思是Expression.Lambda方法调用吗? 添加了我感到困惑的来源。 来源实际上没有向您展示差异吗? @ckv 还展示了几个例子。它还描述了一个 statement lambda,它是“相反的”。举几个例子。 (虽然博客非常需要一个代码显示插件。而且通常看起来有点蹩脚。) 【参考方案1】:

这确实是令人困惑的行话;我们想不出更好的办法。

lambda 表达式是以下任何一个的统称:

x => M(x)
(x, y) => M(x, y)
(int x, int y) => M(x, y)
x =>  return M(x); 
(x, y) =>  return M(x, y); 
(int x, int y) =>  return M(x, y); 

前三个是表达式 lambdas,因为 lambda 运算符的右侧是一个表达式。最后三个是 statement lambdas,因为 lambda 运算符的右侧是一个 block

这也说明了左侧存在三种可能的语法:单个参数名称,或带括号的无类型参数列表,或带括号的类型参数列表。

【讨论】:

这就是区别吗?语句和块内的语句。 @ckv 当编译成Func<T> 时,不是真的。当编译成Expression<Func<T>> 时,是的。例如,一些解析表达式的查询提供者不能处理语句 lambda,或者必须在某个上下文中具有语句 lambda 等等。总之,创建的表达式树是完全不同的,谁在“使用”它可能会很在意那些细节。对于一个普通的Func<T>,当你调用它时运行的底层代码(希望)是一个你不需要担心的抽象。 @Servy 除非您不能将语句 lambda 转换为 Expression。您可以创建一个表示语句的Expression(从 .Net 4.0 开始),但您必须为此手动使用表达式树 API。 你如何与一个回应 C# 说“......我们想不出更好的东西。”的人竞争? @C.Lang:简单,不要竞争;要合作。我认为按照自己的意愿为人服务更具建设性。【参考方案2】:

是的 - 或者我应该说一个定义另一个。

lambda 表达式允许您分配简单的匿名函数。

表达式 lambda 是一种类型的 lambda,它在 lambda 运算符的右侧有一个表达式。

另一种 lambda 表达式是 语句 lambda,因为它在表达式的右侧包含一个语句块 ...

表达式 lambda 采用以下形式:number => (number % 2 == 0) 语句 lambda 采用以下形式:number => return number > 5

【讨论】:

@millimoose,我的英语可能又让我失望了。提问者提到的文章将表达式 lambdas(相对于语句 lambdas)区分为其主体仅包含在单个表达式中的 lambdas。 IIRC “表达式” lambda 可以分配给 Expression<Func<T>> 但“语句” lambda 不能。 @FrédéricHamidi 正确。语句 lambda 和表达式 lambda 是两种不同类型的 lambda 表达式。 lambda 要么包装语句,要么包装表达式。生成的 lambda 本身就是一个表达式(不管它包装了两个中的哪一个)。 @FrédéricHamidi 感谢您的回答,尽管我在那里过于挑剔。 “谁的身体由谁组成”是一个更好的措辞,我对“返回一个表达式”感到困惑,因为我认为 lambda 会返回任何身体的结果。 @millimoose,这就是我说evaluates an expression的原因,但我想那更令人困惑;)【参考方案3】:

lambda 表达式 是一种语法,它允许您直接在代码中创建一个没有名称的函数,作为表达式。

有两种 lambda 表达式,具体取决于它们的主体:

表达式 lambdas,其主体只是一个表达式,例如(i, j) => i + j statement lambdas,其主体是完整的语句,例如(i, j) => return i + j;

【讨论】:

【参考方案4】:

lampda 表达式是一个匿名函数,编译器可以将其转换为Func<T>Expression<Func<T>>(根据使用情况由编译器推断)。

您所说的“表达式 lamdba”是什么意思并不完全清楚,但如果您在播客/网络广播或其他内容中听到过这个短语,它可能指的是 lambda 表达式。或者它可以是属性Expression.Lambda,您可以使用它从 Expression 实例中获取 lambda。

【讨论】:

以上是关于表达式 lambda 和语句 lambda 的区别的主要内容,如果未能解决你的问题,请参考以下文章

为什么C#的Lambda表达式不支持语句

如何用lambda表达式改写LinQ语句?

python基础

语句 lambda 可以替换为表达式 lambda

JAVA801_Lambda表达式的格式使用前提省略模式注意事项和匿名内部类的区别

JavaSE-22.1.7Lambda表达式和匿名内部类的区别