4

我正在为 CIL 编写一个静态分析工具。如果 finally 块可以解释为 try-catch 块并在 catch 内重新抛出,则控制流分析将被简化。在 C# 中,我看不出两者之间的区别

try
{
    // ...
}
finally
{
    // finally code here
}

try
{
    // ...
}
catch
{
    // finally code here
    throw;
}

或之间

try
{
    // ...
}
catch(Exception e)
{
    // catch code here
}
finally
{
    // finally code here
}

try
{
    try
    {
        // ...
    }
    catch (Exception e)
    {
        // catch code here
    }
}
catch
{
    // finally code here
    throw;
}

CIL 中甚至还有 finally 块和 endfinally 指令。应该有区别吧?

4

2 回答 2

14

否 -finally即使没有抛出异常,并且即使另一个块捕获了异常,也会执行一个catch。(无论catch块本身是否抛出异常都是如此。)

哦,如果块从方法返回,也会执行一个finally块。try

基本上,如果您希望代码在执行离开语句时始终执行,finally这就是您想要的。尽管在 C# 中我发现我很少编写显式finally块 -using语句几乎总是使代码更简单。

于 2013-05-11T10:25:18.387 回答
13

补充乔恩的——当然是正确的——答案:你实际上是在描述一个try-fault块。也就是说,一个try-fault块相当于try后面跟着catch-everything 和自动重新 - throw

C# 不支持try-fault块,但 CIL 支持,所以如果您曾经阅读 IL 并看到一个fault块,现在您知道它是什么了。

另外,这样说是对

try{} 
catch {} 
finally {}

相当于

try 
{ 
    try { } 
    catch { } 
} 
finally { }

事实上,在 C# 编译器内部,它就是这样做的;所有 try-catch-finally 块都被重写为 try-finally 内的嵌套 try-catch。这是一个简化的假设,在编写静态分析器时会有所帮助。

于 2013-05-11T14:10:20.433 回答