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

本文关键字:不需要 语句 if 表达式 lambda 不能 简单 为什么 | 更新日期: 2023-09-27 18:27:53

考虑以下分配给事件的 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 赋值被认为是损坏的。

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

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

如果没有{ },则声明表达式主体,{ }它是语句主体。请参阅 Lambda 表达式(C# 编程指南(:

  • 表达式 lambda 返回表达式的结果

  • 语句 lambda 类似于表达式 lambda,不同之处在于语句括在大括号中 [...]语句 lambda 的主体可以包含任意数量的语句。

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

请参阅 lambda 表达式。

有两种类型的 lambda,表达式 Lambdas(无{}(和语句 Lambdas(带 {}(。

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

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

但问题是你在哪里划清界限?

如果

b => if (b) DoSomething()` 

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

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

被允许。或

list => foreach (var item in list) DoSomething(item)
等等

,等等等等...在不知不觉中,您有一个完整的团队支持一个基本微不足道的功能。

功能

中没有错误的唯一可靠方法是不实现该功能。

当前的实现是最佳的,因为它在大多数情况下都有效,并且在其余情况下不会太麻烦(简单的{}不会过多地阻碍可读性,同时使编译器更容易(。

这样

看。 您有一个条件语句,如果正确,则触发一行。

if (stuff) do stuff;

也可以写

if (stuff)
     do stuff;

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

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

然后,您将它与匿名方法结合使用,该方法的行为方式类似

() => do stuff;

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

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

但是现在你正在嵌套它们,但仍然期望能够使用快捷方式。它确实如此,一个捷径,暗示了一个语句的括号。

因此,您将一个快捷方式嵌套在另一个快捷方式中。 C# 只是强制您显式拼写嵌套快捷方式。