准备C#考试。我对语句lambda必须使用大括号{}的事实感到困惑。我从底部的控制问题中了解到这一点。下面的Lambda很好,没有括号。
class A
{
public static Func<float, float> a = (x) => x * x;
}
问题
10 . Which of the following statements about statement lambdas is false?
a . A statement lambda can include more than one statement.
b . A statement lambda cannot return a value.
c . A statement lambda must use braces, { }.
d . If a statement lambda returns a value, it must use a return statement.
答案:
b.
答案 0 :(得分:7)
下面的Lambda没有大括号
是的,但是它是expression lambda而不是statement lambda。从那些文档:
语句lambda类似于表达式lambda,除了语句用括号括起来
这是一个有点奇怪的问题,因为使用大括号是使它成为一个语句lambda。答案 b 绝对是正确的,因为它是唯一的错误断言:语句lambdas 可以返回值。
一个语句lambda肯定可以包含多个语句,并且肯定可以返回一个值,尽管它必须使用return语句来执行此操作:
// Statement lambda with multiple statements, returning a value.
Func<int> statementLambda = () =>
{
int x = 2;
return x * 5;
};
关于术语的一点注意事项:我更喜欢这些术语是“表情身体的lambda”和“块状的lambda”,部分原因是它更符合规范:
匿名功能体:
表达
块
但是,我们现在仍然坚持使用术语:(
要回答dee zg的答案中的观点(以及之后的评论),请考虑以下两个赋值语句:
Action action = () => { Console.WriteLine("Statement lambda"); };
Action action2 = () => Console.WriteLine("Expression lambda");
第二个lambda表达式是表达式lambda。 lambda的主体是表达而不是块。表达式如下:
Console.WriteLine("Expression lambda")
(注意它没有分号;分号属于赋值。)
这对于表达式来说是不寻常的,因为它没有结果。它是一个 invocation-expression ,它是一种 statement-expression 来使用规范术语,并且只允许在几个上下文中使用。虽然在lambda表达式的转换中很好。来自ECMA C# 5 standard的第11.7.1节(“匿名函数转换/一般”):
具体来说,匿名函数F与提供的代理类型D兼容:
...
- 如果
F
的正文是表达式,并且D
的{{1}}返回类型为void
,则F
为async
且D
具有返回类型Task
,然后当F
的每个参数被赋予D
中相应参数的类型时,F的主体是有效表达式(wrt§12),被允许作为 statement-expression (§13.7)。
statement-expression (如第13.7节所述)可以是以下任何一种:
在这种情况下,我们有一个 invocation-expression (调用Console.WriteLine
方法);一个没有结果的人。
请注意,尽管这两个lambda表达式在这里看起来几乎相同,但是有一点不同:语句lambda无法转换为表达式树,而表达式lambda可以:
// Invalid: error CS0834: A lambda expression with a statement body
// cannot be converted to an expression tree
Expression<Action> action = () => { Console.WriteLine("Statement lambda"); };
// Valid
Expression<Action> action2 = () => Console.WriteLine("Expression lambda");
关于表达式分类的进一步阅读,有第12.2.1节:
表达式被分类为以下之一:
...
- 无。当表达式是返回类型为void的方法的调用时,会发生这种情况。分类为空的表达式仅在statement-expression(第13.7节)的上下文中有效。
虽然我们通常认为表达式是计算一个值,但不是每个表达都会这样做。
有关调用表达式的更多详细信息,我们可以转到第12.7.6节(强调我的):
评估调用表达式的结果分类如下:
- 如果 invocation-expression 调用返回void的方法或委托,则结果为空。只有在statement-expression(§13.7)的上下文中或作为lambda-expression(§12.16)的主体的上下文中才允许被分类为nothing的表达式。否则会发生绑定时错误。
- 否则,结果是一个值,具有方法或委托的返回类型的关联类型。 [...]
答案 1 :(得分:0)
你所展示的是表达式lambda,它不需要使用大括号。
相反,当你有语句lambda时,语句lambda的主体必须用大括号括起来。