为什么在lambda中抛出一个C#7特性的异常?

时间:2017-06-21 22:53:15

标签: c# visual-studio-2015 lambda c#-6.0 c#-7.0

此声明不在VS2015中编译,但在VS2017中编译:

var example = new Action( () => throw new Exception()

enter image description here

为了支持在labmda表达式中抛出异常,解析labmdas的方式有什么变化?

特别是因为如果我使用lambda身体,VS2015非常高兴:

enter image description here

我的问题类似于Why can't I throw exceptions from an expression-bodied member?,但我的问题是为什么。从lambda创建表达式树需要扩展编译器会发生什么?

3 个答案:

答案 0 :(得分:6)

在C#6中,() =>必须后跟一个表达式。它可能是一个没有产生任何值的表达式,例如对返回类型为void的方法的调用,但它仍然是一个表达式。

在C#6中,throw只能出现在声明中。完整的throw new Exception("test");是一个声明。注意那里的分号。语法中没有任何内容可以单独支持throw new Exception("test"),分号是其中不可或缺的一部分。

因此,要使其工作,C#7必须允许() =>之后的语句,并且需要支持一种语句而不终止;,或者C#7需要扩展允许throw出现在那里的表达式的定义。后者就是这样。

答案 1 :(得分:3)

C#没有考虑throw有一个类型(甚至不是void),所以throw是一个声明,而不是一个表达式,因此没有任何意义要么用它创建一个lambda,要么用它作为一部分组成更大的表达式。

C#7允许它具有任何类型,因此现在都可以实现这两种类型。

答案 2 :(得分:1)

这是C#7.0的更新,请参阅有关“投掷表达式”的部分:https://blogs.msdn.microsoft.com/dotnet/2017/03/09/new-features-in-c-7-0/