Ответ
Блок finally — это часть конструкции try-catch-finally в C#, предназначенная для гарантированного выполнения кода очистки (cleanup), независимо от того, как было завершено выполнение блока try (или catch).
Когда выполняется finally?
Код в finally выполняется всегда после выхода из блока try (или catch), даже если:
- Исключение было выброшено и перехвачено (
catch). - Исключение было выброшено и НЕ перехвачено (после выполнения
finallyисключение продолжит всплывать). - В блоке
tryилиcatchбыл выполненreturn. - В блоке
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).
Видео-ответы
▶
▶
▶
▶
▶
▶
▶