Порядок выполнения try, catch и finally блокирует

Предположим, у меня есть код C#, подобный этому:

try {
    Method1();
}
catch(...) {
    Method2();
}
finally {
    Method3();
}
Method4();
return;

Мой вопрос заключается в том, что при условии, что исключение не выдается, будет ли Method3() выполняться перед Method4(), или это finally блок выполняется только до return, continue или же break заявление?

3 ответа

Решение

Да, finally блок из try-catch будет выполнен в порядке, как вы ожидаете, а затем выполнение перейдет к остальной части кода (после завершения всего try-catch-finally блок).

Вы можете думать обо всем try-catch-finally block как отдельный компонент, который будет функционировать так же, как любой другой вызов метода (с кодом, выполняемым до и после него).

// Execute some code here

// try-catch-finally (the try and finally blocks will always be executed
// and the catch will only execute if an exception occurs in the try)

// Continue executing some code here (assuming no previous return statements)

пример

try 
{
    Console.WriteLine("1");
    throw new Exception();
}
catch(Exception) 
{
    Console.WriteLine("2");
}
finally 
{
    Console.WriteLine("3");
}
Console.WriteLine("4");
return;

Вы можете увидеть пример этого в действии, который приводит к следующему выводу:

1
2
3
4

Последовательность всегда будет

try 
--> catch(if any exception occurs) 
--> finally (in any case) 
--> rest of the code (unless the code returns or if there is any uncaught exceptions from any of the earlier statements)

Полезный ресурс: https://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx

Мой вопрос, при условии, что исключение не выдается, будет ли Method3() выполняться перед Method4(),

Да, Method3 будет выполнен раньше Method4 потому что вне зависимости от того, выдано исключение или нет, выполнение перейдет к блоку finally, а затем продолжится оттуда.

или это то, что блок finally выполняется только перед оператором return, continue или break?

Нет, он всегда выполняется после блока try, независимо от того, было ли исключение или нет.

Важная точка

Если у вас есть это:

try 
{
    DoOne();
    DoTwo();
    DoThree();
}
catch{ // code}
finally{ // code}

Если исключение выдается DoOne() затем DoTwo() а также DoThree() никогда не будет называться. Поэтому НЕ думайте, что весь try Блок всегда будет выполняться. На самом деле, будет выполнена только часть до тех пор, пока не будет сгенерировано исключение, а затем выполнение переходит к catch блок.

Наконец будет выполняться всегда - несмотря на то, было ли исключение.

Другие вопросы по тегам