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

В чём разница между throw и throw new Exception?

1.7 Middle🔥 121 комментариев
#Основы C# и .NET

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

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

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

Разница между throw и throw new Exception

Ключевое различие между throw и throw new Exception заключается в повторном выбрасывании существующего исключения и создании нового исключения соответственно. Эта разница критически важна для корректной обработки ошибок, отладки и поддержки кода.

throw - повторное выбрасывание существующего исключения

Используется внутри блока catch для повторного выбрасывания того же самого исключения, которое было перехвачено. Это позволяет:

  • Сохранить оригинальный стек вызовов и детали исключения
  • Добавить дополнительную логику обработки перед повторным выбросом
  • Прокинуть исключение на более высокий уровень обработки
try
{
    SomeRiskyOperation();
}
catch (IOException ex)
{
    // Логируем исключение, но сохраняем оригинальную информацию
    Logger.LogError("IO операция завершилась ошибкой", ex);
    
    // Повторно выбрасываем ТО ЖЕ САМОЕ исключение
    throw;
}

throw new Exception - создание нового исключения

Создает и выбрасывает новый экземпляр исключения, что приводит к:

  • Потере оригинального стека вызовов (если не использовать конструктор с внутренним исключением)
  • Созданию исключения с новым сообщением или типом
  • Возможности обернуть оригинальное исключение в более подходящий тип
try
{
    ParseConfigurationFile();
}
catch (FormatException ex)
{
    // Создаем НОВОЕ исключение, теряя оригинальный стек
    throw new ConfigurationException("Неверный формат конфигурационного файла");
    
    // Лучший вариант - сохранить оригинальное исключение как InnerException
    throw new ConfigurationException("Неверный формат конфигурационного файла", ex);
}

Практические различия и рекомендации

Сохранение стека вызовов

// Пример, демонстрирующий разницу в стеке вызовов
public void MethodA()
{
    try
    {
        MethodB();
    }
    catch (Exception ex)
    {
        Console.WriteLine("Stack trace with 'throw':");
        Console.WriteLine(ex.StackTrace);
        throw; // Сохраняет стек от MethodB
    }
}

public void MethodB()
{
    throw new InvalidOperationException("Original error");
}

// При использовании 'throw new Exception' стек будет указывать на место нового throw

Рекомендации по использованию

  1. Используйте throw без параметров когда:

    • Нужно просто логировать и повторно выбросить то же исключение
    • Требуется сохранить полную отладочную информацию
    • Исключение уже имеет правильный тип для вышестоящих обработчиков
  2. Используйте throw new Exception когда:

    • Необходимо обернуть низкоуровневое исключение в более семантически правильное
    • Нужно добавить дополнительную информацию в сообщение
    • Обязательно передавайте оригинальное исключение как InnerException
  3. Паттерн обертывания исключений:

public void ProcessData(string data)
{
    try
    {
        ValidateAndProcess(data);
    }
    catch (ArgumentException ex)
    {
        // Обертываем в более специфичное исключение
        throw new DataProcessingException(
            $"Ошибка обработки данных: {data}", 
            ex // Сохраняем оригинальное исключение
        );
    }
    catch (FormatException ex)
    {
        // Логируем и повторно выбрасываем без изменений
        LogWarning("Неверный формат данных", ex);
        throw; // Сохраняем стек и детали
    }
}

Производительность и best practices

  • throw обычно быстрее, так как не создает новый объект исключения
  • Всегда предпочитайте throw если нужно просто повторно выбросить то же исключение
  • При создании пользовательских исключений переопределяйте конструкторы для поддержки InnerException
  • Избегайте "скрытия" исключений - всегда сохраняйте оригинальную причину ошибки

Вывод

Выбор между throw и throw new Exception зависит от конкретного сценария обработки ошибок. throw сохраняет оригинальный контекст ошибки и подходит для сквозной передачи исключений. throw new Exception позволяет трансформировать исключения в более подходящие типы, но требует аккуратного сохранения оригинальной информации через механизм InnerException. Правильное использование этих конструкций улучшает диагностику проблем и поддерживаемость кода.

В чём разница между throw и throw new Exception? | PrepBro