为什么这“最终”执行?
如果你运行下面的代码,它实际上在每次调用goto后执行finally:
int i = 0; Found: i++; try { throw new Exception(); } catch (Exception) { goto Found; } finally { Console.Write("{0}\t", i); }
为什么?
你为什么期望它不执行?
如果你有try / catch / finally或try / finally阻塞, 那么无论你在try或catch块中使用的代码 大多数时间都是块执行。
而不是goto,考虑’返回’。
//imagine this try/catch/finally block is inside a function with return type of bool. try { throw new Exception(); } catch (Exception) { return false; //Let's say you put a return here, finally block still executes. } finally { Console.WriteLine("I am in finally!"); }
以下文本来自C#语言规范 ( 8.9.3 goto语句 )
goto语句执行如下:
- 如果goto语句退出一个或多个具有关联的finally块的try块,则控制最初被转移到最里面的try语句的finally块。 当控制到达finally块的结束点时,控制权转移到下一个封闭的try语句的finally块。 重复此过程,直到执行了所有介入的try语句的finally块。
- 控制权转移到goto语句的目标。
给出答案的要点 – 当控制通过任何方式离开受保护区域时,无论是“返回”,“转到”,“中断”,“继续”还是“抛出”,执行“最终”都是正确的。 但是,我注意到几乎每个答案都说“最后块总是运行”。 finally块并不总是运行。 在许多情况下,finally块不会运行。
谁想尝试将它们全部列出?
似乎合理。 始终在try
或catch
之后运行finally
块。
同样
try { // do something return; } finally { // do something else }
将始终运行finally
块。 编辑 – 但请参阅Eric上面的评论。
这是设计的。 在exception处理程序中,您可以执行一些特定于exception的操作。 在finally块中,您应该进行资源清理 – 这就是无论exception处理代码是什么,始终执行finally块的原因。
正如人们所提到的,无论程序流程如何, finally
都会运行。 当然, finally
块是可选的,所以如果你不需要它,不要使用它。
因为期望finally
语句在离开try
之后执行(或者在catch
exception时捕获)。 这包括您进行goto通话时。
这是finally
块的重点。 它总是执行(几乎)。