← Назад к вопросам

Что такое try/catch?

1.0 Junior🔥 141 комментариев
#Основы C# и .NET

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое try/catch в C#?

Try/catch — это конструкция языка C# для обработки исключений (exceptions), которая позволяет безопасно выполнять код, который может вызвать ошибку, и корректно реагировать на возникновение исключительных ситуаций без аварийного завершения программы.

Основная структура и принцип работы

Базовый синтаксис выглядит следующим образом:

try
{
    // Код, который может вызвать исключение
    int divisor = 0;
    int result = 10 / divisor; // Вызовет DivideByZeroException
}
catch (DivideByZeroException ex)
{
    // Обработка конкретного типа исключения
    Console.WriteLine($"Ошибка деления на ноль: {ex.Message}");
}
catch (Exception ex)
{
    // Общий обработчик для всех исключений
    Console.WriteLine($"Произошла ошибка: {ex.Message}");
}
finally
{
    // Код, который выполнится в любом случае
    Console.WriteLine("Блок finally выполнен.");
}

Ключевые компоненты конструкции

  1. Блок try:

    • Содержит потенциально опасный код, который может сгенерировать исключение.
    • При возникновении исключения выполнение кода в try немедленно прерывается.
  2. Блок catch:

    • Определяет обработчики для различных типов исключений.
    • Может быть несколько блоков catch для обработки разных типов исключений.
    • Обработчики проверяются сверху вниз — важен порядок от более конкретных к более общим типам.
  3. Блок finally (опциональный)**:

    • Выполняется всегда, независимо от того, было выброшено исключение или нет.
    • Используется для освобождения ресурсов (закрытие файлов, соединений с БД).

Типы исключений и иерархия

В C# все исключения наследуются от базового класса System.Exception. Важные производные классы:

// SystemException - исключения, генерируемые CLR
// ArgumentException, ArgumentNullException - неверные аргументы
// InvalidOperationException - недопустимая операция
// IOException, FileNotFoundException - ошибки ввода-вывода
// DivideByZeroException, OverflowException - арифметические ошибки

Лучшие практики использования try/catch

  • Избегайте пустых блоков catch — это скрывает ошибки:

    // ПЛОХОЙ ПРИМЕР
    try { /* код */ } 
    catch { /* пусто! ошибка проигнорирована */ }
    
    // ХОРОШИЙ ПРИМЕР
    try { /* код */ }
    catch (SpecificException ex) 
    { 
        Log.Error(ex, "Контекст ошибки");
        // При необходимости - повторно выбросить
        throw; 
    }
    
  • Используйте конкретные типы исключений вместо общего Exception, когда это возможно.

  • Не злоупотребляйте try/catch для управления логикой программы — исключения должны обрабатывать действительно исключительные ситуации, а не обычные условия выполнения.

  • Всегда освобождайте ресурсы в блоке finally или используйте конструкцию using для объектов, реализующих IDisposable.

Пример с использованием ресурсов

FileStream fileStream = null;
try
{
    fileStream = new FileStream("file.txt", FileMode.Open);
    // Работа с файлом
    byte[] buffer = new byte[1024];
    await fileStream.ReadAsync(buffer, 0, buffer.Length);
}
catch (FileNotFoundException ex)
{
    Console.WriteLine($"Файл не найден: {ex.FileName}");
}
catch (IOException ex)
{
    Console.WriteLine($"Ошибка ввода-вывода: {ex.Message}");
}
finally
{
    // Гарантированное освобождение ресурса
    fileStream?.Dispose();
}

// Альтернатива с using (рекомендуемый способ)
try
{
    using (var stream = new FileStream("file.txt", FileMode.Open))
    {
        // Автоматический вызов Dispose() при выходе из блока
    }
}
catch (FileNotFoundException ex)
{
    Console.WriteLine($"Файл не найден: {ex.FileName}");
}

Фильтры исключений (C# 6.0 и выше)

C# 6.0 представил фильтры исключений, которые позволяют более точно контролировать обработку:

try
{
    // Код, который может вызвать исключение
}
catch (HttpRequestException ex) when (ex.StatusCode == 404)
{
    Console.WriteLine("Ресурс не найден (404)");
}
catch (HttpRequestException ex) when (ex.StatusCode == 500)
{
    Console.WriteLine("Внутренняя ошибка сервера (500)");
}

Важные особенности

  1. Производительность — генерация и обработка исключений дороже, чем обычное выполнение кода, поэтому не используйте их для контроля нормального потока выполнения.

  2. Стек вызовов — при перехвате исключения сохраняется информация о стеке вызовов, что помогает в отладке.

  3. Повторная генерация исключений — используйте throw; для повторной генерации исходного исключения (сохраняет стек вызовов), а не throw ex; (теряет исходный стек).

Конструкция try/catch/finally является фундаментальным механизмом обеспечения отказоустойчивости приложений на C#, позволяя корректно обрабатывать ошибки, логировать их, освобождать ресурсы и поддерживать стабильную работу программы даже в нештатных ситуациях.

Что такое try/catch? | PrepBro