在.net中,最终等同于try-catch-throw

本文关键字:等同于 try-catch-throw net | 更新日期: 2023-09-27 18:13:11

我正在为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指令。肯定有区别,对吧?

在.net中,最终等同于try-catch-throw

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

哦,如果try块从方法返回,finally块也将被执行。

基本上,如果你希望代码总是在执行离开语句时执行,finally就是你想要的。虽然在c#中我发现我很少写显式的finally块- using语句几乎总是使代码更简单。

添加到Jon的答案中——当然是正确的——你实际上是在描述一个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。这是一个简化的假设,可以帮助编写静态分析程序。