16

为什么这个 lambda 表达式不能编译?

Action a = () => throw new InvalidOperationException();

猜想很好,但我非常感谢对 C# 语言规范或其他文档的引用。

是的,我知道以下内容是有效的并且可以编译:

Action a = () => { throw new InvalidOperationException(); };

这个博客文章中描述了我会使用这样的东西的上下文。

4

5 回答 5

19

唔。我有答案,但不是很好。

我不相信有“扔”的表达方式。有一个 throw语句,但不仅仅是一个表达式。将此与“Console.WriteLine()”进行比较,后者是具有 void 类型的方法调用表达式。

作为并行,您不能将 switch 语句或 if 语句等作为 lambda 的主体。你只能有一个表达式或一个块(第 7.14 节)。

这有什么帮助吗?

于 2008-10-31T17:41:20.067 回答
15

这是我的看法:

throw是语句,不是表达式。

和参考:

12.3.3.11 抛出语句

对于形式的语句 stmt

throw expr;

expr开头的v的确定赋值状态与stmt开头的v的确定赋值状态相同。

为了解释本质,也许人们应该考虑一下表达式在 C# lambda 构造中的含义。它只是语法糖:

delegate () { return XXX; }

XXX表达式在哪里

于 2008-10-31T17:35:08.427 回答
1

我可以从这里找到的所有参考资料:

http://msdn.microsoft.com/en-us/library/ms364047(VS.80).aspx#cs3spec_topic4

表明您有两个选择:

Action a = () => { throw new InvalidOperationException(); };

或者

Action a = () => throw new InvalidOperationException()

注意缺少的 ; 最后。是的,这对我来说也没有意义。他们在规范中给出的例子是:

x => x + 1                     // Implicitly typed, expression body
x => { return x + 1; }         // Implicitly typed, statement body
(int x) => x + 1               // Explicitly typed, expression body
(int x) => { return x + 1; }   // Explicitly typed, statement body
(x, y) => x * y               // Multiple parameters
() => Console.WriteLine()      // No parameters

不知道这有多大帮助 - 我不知道你在什么上下文中使用它,而不是放一个 ; 最后在 C# 中没有意义

不同之处可能在于它是一个表达式主体——而不是一个语句——如果它没有 {}。这意味着你的 throw 在那里无效,因为它是一个语句,而不是一个表达式!

于 2008-10-31T17:27:49.313 回答
1

您不能从非作用域的 lambda 返回或抛出。

这样想...如果您不提供 {},编译器会确定您的隐式返回值是什么。当您throw从 lambda 内部时,没有返回值。你甚至不回来void。为什么编译器团队不处理这种情况,我不知道。

于 2008-10-31T17:35:52.090 回答
0

不是什么大惊喜。Lambda 表达式是函数式编程的一个方面。异常是过程编程的一个方面。两种编程风格之间的 C# 网格并不完美。

于 2008-10-31T17:52:28.110 回答