В каком порядке следует указывать несколько блоков catch в C#?

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

Ответ

Блоки 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) будет первым, все последующие блоки станут недостижимым кодом.