C# 操作 lambda 限制

问题描述 投票:0回答:5

为什么这个 lambda 表达式无法编译?

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

推测没问题,但我真的很感激 C# 语言规范或其他文档的参考。

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

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

我使用类似内容的上下文在这篇博文中有所描述。

c# lambda
5个回答
19
投票

嗯。我已经有了答案,但不太好。

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

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

有什么帮助吗?


15
投票

这是我的看法:

throw
是一个陈述,而不是一个表达。

以及参考:

12.3.3.11 抛出语句

对于以下形式的语句 stmt

throw expr;

v 的确定赋值状态 expr 的开头是相同的 作为 v 的确定赋值状态 在 stmt 的开头。

为了解释其本质,也许我们应该考虑一下表达式在 C# lambda 构造中意味着什么。它只是语法糖:

delegate () { return XXX; }

其中

XXX
是一个表达式


1
投票

您无法从无作用域的 lambda 中返回或抛出。

这样想...如果您不提供 {},编译器将确定您的隐式返回值是什么。 当您在 lambda 中

throw
时,没有返回值。 你甚至不会回来
void
。 我不知道为什么编译器团队不处理这种情况。


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 在那里无效,因为它是一个语句,而不是一个表达式!


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.