В .NET, наконец, эквивалентно try-catch-throw?

Я пишу инструмент статического анализа для CIL. Анализ потока управления был бы упрощен, если бы блоки finally можно было интерпретировать как блоки try-catch с повторным броском внутри catch. В С# я не вижу разницы между

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. Должна быть разница, не так ли?


person Călin Darie    schedule 11.05.2013    source источник


Ответы (2)


Нет — блок finally выполняется, даже если исключение не выдается, и также, даже если исключение перехватывает другой блок catch. (Это верно независимо от того, генерирует ли блок catch исключение или нет.)

Да, и блок finally будет также выполняться, если блок try возвращает значение из метода.

По сути, если вы хотите, чтобы код всегда выполнялся, когда выполнение покидает оператор, вам нужно finally. Хотя в C# я редко пишу явный блок finally — оператор using почти всегда упрощает код.

person Jon Skeet    schedule 11.05.2013

Чтобы добавить к ответу Джона — правильному, конечно — ответу: на самом деле вы описываете блок try-fault. То есть блок try-fault эквивалентен блоку try, за которым следует catch - все и автоматический повтор throw.

C# не поддерживает блоки try-fault, но CIL поддерживает, так что если вы когда-нибудь читали IL и видели блок fault, теперь вы знаете, что это такое.

Кроме того, правильно сказать, что

try{} 
catch {} 
finally {}

эквивалентно

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

И на самом деле внутри компилятора C# это то, что он делает; все блоки try-catch-finally переписываются во вложенный блок try-catch внутри блока try-finally. Это упрощающее предположение, которое может помочь при написании статического анализатора.

person Eric Lippert    schedule 11.05.2013