为什么这个 lambda 表达式不能编译?
Action a = () => throw new InvalidOperationException();
猜想很好,但我非常感谢对 C# 语言规范或其他文档的引用。
是的,我知道以下内容是有效的并且可以编译:
Action a = () => { throw new InvalidOperationException(); };
这个博客文章中描述了我会使用这样的东西的上下文。
为什么这个 lambda 表达式不能编译?
Action a = () => throw new InvalidOperationException();
猜想很好,但我非常感谢对 C# 语言规范或其他文档的引用。
是的,我知道以下内容是有效的并且可以编译:
Action a = () => { throw new InvalidOperationException(); };
这个博客文章中描述了我会使用这样的东西的上下文。
唔。我有答案,但不是很好。
我不相信有“扔”的表达方式。有一个 throw语句,但不仅仅是一个表达式。将此与“Console.WriteLine()”进行比较,后者是具有 void 类型的方法调用表达式。
作为并行,您不能将 switch 语句或 if 语句等作为 lambda 的主体。你只能有一个表达式或一个块(第 7.14 节)。
这有什么帮助吗?
这是我的看法:
throw
是语句,不是表达式。
和参考:
12.3.3.11 抛出语句
对于形式的语句 stmt
throw expr;
expr开头的v的确定赋值状态与stmt开头的v的确定赋值状态相同。
为了解释本质,也许人们应该考虑一下表达式在 C# lambda 构造中的含义。它只是语法糖:
delegate () { return XXX; }
XXX
表达式在哪里
我可以从这里找到的所有参考资料:
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 在那里无效,因为它是一个语句,而不是一个表达式!
您不能从非作用域的 lambda 返回或抛出。
这样想...如果您不提供 {},编译器会确定您的隐式返回值是什么。当您throw
从 lambda 内部时,没有返回值。你甚至不回来void
。为什么编译器团队不处理这种情况,我不知道。
不是什么大惊喜。Lambda 表达式是函数式编程的一个方面。异常是过程编程的一个方面。两种编程风格之间的 C# 网格并不完美。