为什么在Lambda内引发C#7功能异常? [英] Why is throwing an exception inside lambda a C# 7 feature?
问题描述
此语句在VS2015中不编译,但在VS2017中:
This statement doesn't compile in VS2015, but does in VS2017:
var example = new Action( () => throw new Exception()
为了支持在labmda表达式内引发异常,labmdas的解析方式必须进行哪些更改?
What had to change in the way labmdas are parsed in order to support throwing an exception inside a labmda expression?
特别是因为如果我使用lambda主体,则VS2015非常高兴:
Especially because if I use a lambda body, VS2015 is perfectly happy:
我的问题类似于为什么不能我抛出了来自表情健全成员的异常吗?,但是我的问题是为什么.在需要扩展编译器的lambda中创建表达式树时会发生什么?
My question is similar to Why can't I throw exceptions from an expression-bodied member?, but my question, is why. What had to happen in the creation of an expression tree from a lambda that necessitated extending the compiler?
推荐答案
在C#6中,必须在()=>
后加上一个表达式.它可能是一个不产生任何值的表达式,例如对返回类型为 void
的返回值的方法的调用,但这仍然是一个表达式.
In C# 6, () =>
had to be followed by an expression. It could be an expression that did not produce any value, such a call to a method with a return type of void
, but that's still an expression.
在C#6中, throw
只能出现在一条语句中.完整的引发新的Exception("test");
是一条语句.请注意其中的分号.语法中没有任何东西可以单独支持抛出新的Exception("test")
,分号是其中不可或缺的一部分.
In C# 6, throw
could only appear in a statement. The complete throw new Exception("test");
is a statement. Note the semicolon in there. There was nothing in the grammar to support throw new Exception("test")
on its own, the semicolon was an integral part of it.
因此,要使此功能正常运行,要么C#7要么必须允许()=>
之后的语句,而且需要支持某种形式的语句而无需终止;
或C#7将需要扩展表达式的定义,以允许 throw
出现在其中.后者是发生了什么.
Therefore, to get this to work, either C# 7 would have to allow statements after () =>
and would need to support a form of statements without the terminating ;
, or C# 7 would need to extend the definition of an expression to allow throw
to appear there. The latter is what happened.
这篇关于为什么在Lambda内引发C#7功能异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!