Для таких вопросов я обычно открываю пустой проект консольного приложения в Visual Studio и пишу небольшой пример программы:
using System;
class Program
{
static void Main(string[] args)
{
try
{
try
{
throw new Exception("exception thrown from try block");
}
catch (Exception ex)
{
Console.WriteLine("Inner catch block handling {0}.", ex.Message);
throw;
}
finally
{
Console.WriteLine("Inner finally block");
throw new Exception("exception thrown from finally block");
Console.WriteLine("This line is never reached");
}
}
catch (Exception ex)
{
Console.WriteLine("Outer catch block handling {0}.", ex.Message);
}
finally
{
Console.WriteLine("Outer finally block");
}
}
}
При запуске программы вы увидите точный порядок, в котором catch
и finally
выполняются блоки. Обратите внимание, что код в блоке finally после создания исключения не будет выполнен (фактически, в этом примере программы Visual Studio даже предупредит вас, что обнаружил недоступный код):
Исключение обработки внутреннего блока catch, выданное из блока try.
Внутренний, наконец, блок
Исключение обработки внешнего блока catch, выданное из блока finally.
Наружный наконец-то блок
Дополнительное замечание
Как отметил Михаил Даматов, исключение из try
блока будет «съедено», если вы не обработаете его во (внутреннем) catch
блоке. Фактически, в приведенном выше примере повторно выброшенное исключение не появляется во внешнем блоке перехвата. Чтобы сделать это еще более понятным, взгляните на следующий слегка измененный пример:
using System;
class Program
{
static void Main(string[] args)
{
try
{
try
{
throw new Exception("exception thrown from try block");
}
finally
{
Console.WriteLine("Inner finally block");
throw new Exception("exception thrown from finally block");
Console.WriteLine("This line is never reached");
}
}
catch (Exception ex)
{
Console.WriteLine("Outer catch block handling {0}.", ex.Message);
}
finally
{
Console.WriteLine("Outer finally block");
}
}
}
Как видно из вывода, внутреннее исключение «потеряно» (т.е. проигнорировано):
Внутренний, наконец, блок
Исключение обработки внешнего блока catch, выданное из блока finally.
Наружный наконец-то блок