Ответ
Блоки catch должны быть указаны в порядке от наиболее специфичного исключения к наиболее общему. Компилятор C# требует этого и выдаст ошибку CS0160, если более общий блок перехватит исключение раньше производного от него.
Правильный порядок:
try
{
// Код, который может вызвать исключение
File.ReadAllText("missing.txt");
}
catch (FileNotFoundException ex) // Наиболее специфичное
{
// Обрабатываем именно случай отсутствия файла
Console.WriteLine($"Файл не найден: {ex.FileName}");
// Можно создать файл по умолчанию
}
catch (IOException ex) // Более общее (FileNotFoundException наследуется от него)
{
// Обрабатываем другие ошибки ввода-вывода (нет прав, диск полон и т.д.)
Console.WriteLine($"Ошибка IO: {ex.Message}");
_logger.LogWarning(ex, "IO error occurred");
}
catch (Exception ex) // Самое общее исключение
{
// Перехватываем всё остальное (OutOfMemoryException, ArgumentException и пр.)
// Обычно здесь только логирование и аварийное завершение операции
_logger.LogError(ex, "Unexpected error");
throw; // Пробрасываем дальше, если не можем восстановиться
}
Почему порядок важен: Выполняется первый блок catch, тип исключения которого совместим с выброшенным исключением. Если catch (Exception) будет первым, все последующие блоки станут недостижимым кодом.