【发布时间】:2016-12-07 19:21:03
【问题描述】:
我看过这个例子:
static void Main(string[] args)
{
Console.WriteLine("Start");
try
{
SomeOperation();
}
catch (Exception) when (EvaluatesTo())
{
Console.WriteLine("Catch");
}
finally
{
Console.WriteLine("Outer Finally");
}
}
private static bool EvaluatesTo()
{
Console.WriteLine($"EvaluatesTo: {Flag}");
return true;
}
private static void SomeOperation()
{
try
{
Flag = true;
throw new Exception("Boom");
}
finally
{
Flag = false;
Console.WriteLine("Inner Finally");
}
}
产生下一个输出:
Start
EvaluatesTo: True
Inner Finally
Catch
Outer Finally
这对我来说听起来很奇怪,我正在寻找对这个命令的一个很好的解释,以便将它总结在我的脑海中。我期待finally 块在when 之前执行:
Start
Inner Finally
EvaluatesTo: True
Catch
Outer Finally
文档说明这个执行顺序是正确的,但是没有详细说明为什么会这样,以及这里执行顺序的规则到底是什么。
【问题讨论】:
-
@RahulTripathi 不,我的问题是关于 C# 6.0 中交换的执行顺序,这个问题在 6.0 之前的原版 C# 中有直接执行顺序
-
这是 when 子句如何工作的必然结果。 CLR 无法确定 finally 块需要执行什么,直到 之后 它已经确定了哪个 catch 子句将处理异常。只有这样它才能开始展开堆栈,同时执行 finally 块。 when 表达式可能是无意的副作用,这就是为什么在 v6 之前它被排除在 C# 语言之外的原因。
-
@HansPassant 为什么,具体来说,这是真的:“CLR 无法弄清楚 finally 块需要执行什么,直到它弄清楚什么 catch 子句将处理异常。”?跨度>
-
就像踩着自行车不知道要去哪里。您无法决定是左转还是右转。
-
这是避免
when子句中副作用的一个很好的理由。 ;)