Порядок выполнения 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
блок.
Наконец будет выполняться всегда - несмотря на то, было ли исключение.