为什么C#lambda表达式不能由一个简单的if语句组成,而不需要大括号?

时间:2013-08-15 13:31:11

标签: c# lambda

考虑以下分配给事件的lambda表达式。

foo.BarEvent += (s, e) => if (e.Value == true) DoSomething();

这看起来很简单,只包含一行代码。那么为什么我从调试器中得到以下2个错误?

  

无效的表达式术语'if'


  

只有赋值,调用,递增,递减,等待和新对象表达式才能用作语句

要解决此问题,您只需将if语句包装在括号中即可。

foo.BarEvent += (s, e) => { if (e.Value == true) DoSomething(); };
//Errors now disappear!

我理解这些错误消息的含义。我不明白的是为什么单条件if语句会成为编译器的问题,以及为什么第一个lambda赋值被认为是破坏的。

有人可以解释一下这个问题吗?

4 个答案:

答案 0 :(得分:37)

如果没有{ },则声明一个表达式正文,{ }它是一个声明正文。见Lambda Expressions (C# Programming Guide)

  • expression lambda返回表达式的结果

  • statement lambda类似于表达式lambda,除了语句括在括号中[...]语句lambda的主体可以包含任意数量的语句。

因此,如果您需要语句而不是表达式,请使用大括号。

答案 1 :(得分:9)

请参阅Lambda Expressions

有两个类型的lambdas,Expression Lambdas(无{})和Statement Lambdas(带{})。

它们之间的主要区别在于Expression Lambdas被定义为返回由右侧计算的。但是if()是一个陈述,而不是表达。没有与if相关联的值。您会注意到您提供的错误消息中的所有“允许”语言元素都是表达式:它们计算

答案 2 :(得分:0)

据我了解,实现这一点不是问题。 C#团队已经实现了更加可怕的功能(例如LINQ)

但问题是你在哪里画线?

如果

b => if (b) DoSomething()` 

是允许的,那么,为什么不应该

b => if (b) {DoSomething1(); DoSomething2();}

被允许。或者

list => foreach (var item in list) DoSomething(item)
等等等...... 在你知道它之前,你有一个完整的团队支持一个基本上微不足道的功能。

唯一确定功能中存在错误的方法是not implement the feature

当前的实现是最佳的,因为它适用于大多数情况,并且它在其余部分中并不太麻烦(简单的{}不会过多地妨碍可读性,同时使编译器更容易)。

答案 3 :(得分:-1)

这样看待这个。你有一个条件语句,如果正确的话会触发一行。

if (stuff) do stuff;

也可以写

if (stuff)
     do stuff;

因为您只调用一行代码,所以不需要两个括号。如果它更多,那么你将不得不使用括号。

if (stuff)
{
     do stuff;
     do more stuff;
}

然后你将它与匿名方法结合起来,行为方式类似

() => do stuff;

多个语句使用括号,就像条件一样。

() => {do stuff; do more stuff;}

但是现在你正在筑巢,但仍然希望能够使用捷径。 这究竟是什么,一个捷径暗示了一个单一陈述的括号。

因此,您在另一个快捷方式中嵌套了一个快捷方式。 C#只是强迫你明确拼出嵌套的快捷方式。