为什么这"最终"执行?

Kre*_*dns 17 c# goto exception try-catch-finally

如果你运行下面的代码,它实际上在每次调用goto后执行finally:

    int i = 0;
Found:
    i++;
    try
    {
        throw new Exception();
    }
    catch (Exception)
    {
        goto Found;
    }
    finally
    {
        Console.Write("{0}\t", i);
    }
Run Code Online (Sandbox Code Playgroud)

为什么?

Fre*_*örk 36

以下文本来自C#语言规范(8.9.3 goto语句)


goto语句执行如下:

  • 如果goto语句退出一个或多个具有关联的finally块的try块,则控制最初被转移到最里面的try语句的finally块.当控制到达finally块的结束点时,控制权转移到下一个封闭的try语句的finally块.重复此过程,直到执行了所有介入的try语句的finally块.
  • 控制权转移到goto语句的目标.


Sol*_*ogi 28

你为什么期望它不执行?

如果你有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!");
}
Run Code Online (Sandbox Code Playgroud)

  • @ Pure.Krome,你不能把一个return语句放在finally块中. (7认同)
  • @ Pure.Krome,正如Jonathon Watney所说,你会得到一个"编译器错误CS0157:控制不能离开最终条款的主体". (3认同)
  • 如果你有'回归真实'会发生什么?在finally块中(针对上面的示例代码).得到了什么?虚假还是真实? (2认同)

Eri*_*ert 13

给出答案的要点 - 当控制通过任何方式离开受保护区域时,无论是"返回","转到","中断","继续"还是"抛出",执行"最终"都是正确的.但是,我注意到几乎每个答案都说"最后一块总是运行". finally块并不总是运行.在很多情况下,finally块不会运行.

谁想尝试列出所有这些?

  • 科林,确实,关键在于控制权何时离开。如果控制没有离开,则 finally 块不会执行!例如,try-protected 区域可能包含一个无限循环。 (2认同)