Что такое блок finally в C#?

«Что такое блок finally в C#?» — вопрос из категории C# Core, который задают на 28% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Блок finally — это часть конструкции try-catch-finally в C#, предназначенная для гарантированного выполнения кода очистки (cleanup), независимо от того, как было завершено выполнение блока try (или catch).

Когда выполняется finally? Код в finally выполняется всегда после выхода из блока try (или catch), даже если:

  1. Исключение было выброшено и перехвачено (catch).
  2. Исключение было выброшено и НЕ перехвачено (после выполнения finally исключение продолжит всплывать).
  3. В блоке try или catch был выполнен return.
  4. В блоке try или catch был выполнен break или continue, ведущий выходу из блока.

Типичный use-case — освобождение неуправляемых ресурсов:

FileStream fileStream = null;
try
{
    fileStream = File.OpenRead("data.txt");
    // Чтение данных, которое может вызвать IOException
    var data = new byte[fileStream.Length];
    fileStream.Read(data, 0, (int)fileStream.Length);
}
catch (IOException ex)
{
    Console.WriteLine($"Ошибка чтения файла: {ex.Message}");
}
finally
{
    // Этот код выполнится в любом случае: и при успехе, и при исключении.
    // Критически важно закрыть файловый дескриптор.
    fileStream?.Close();
    // В современных C# для этого используют 'using', который компилируется в try-finally.
}

Современная альтернатива — оператор using: Для объектов, реализующих IDisposable, блок finally с вызовом Dispose() можно заменить на:

using (var fileStream = File.OpenRead("data.txt"))
{
    // Работа с fileStream
} // Dispose() будет вызван автоматически здесь, даже при исключении

Когда finally НЕ выполнится? В крайних случаях: при фатальной ошибке среды (Environment.FailFast), переполнении стека (StackOverflowException) или аварийном завершении процесса (например, kill -9).