C#

Try catch в C#: как поймать ошибку и не уронить программу

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

Простой пример:

try
{
    int number = Convert.ToInt32("abc");
    Console.WriteLine(number);
}
catch
{
    Console.WriteLine("Не удалось преобразовать текст в число");
}

Без try catch программа завершилась бы с ошибкой. С catch она выводит понятное сообщение

Пример с вводом пользователя

Пользователь может ввести не число, а текст:

Console.Write("Введите возраст: ");
string? input = Console.ReadLine();

try
{
    int age = Convert.ToInt32(input);
    Console.WriteLine($"Возраст: {age}");
}
catch
{
    Console.WriteLine("Возраст нужно вводить числом");
}

Проверьте ввод:

25

и:

abc

Во втором случае программа не упадет

Несколько catch-блоков

Можно ловить разные ошибки отдельно:

try
{
    Console.Write("Первое число: ");
    int a = Convert.ToInt32(Console.ReadLine());

    Console.Write("Второе число: ");
    int b = Convert.ToInt32(Console.ReadLine());

    Console.WriteLine(a / b);
}
catch (FormatException)
{
    Console.WriteLine("Нужно вводить только числа");
}
catch (DivideByZeroException)
{
    Console.WriteLine("На ноль делить нельзя");
}

Так пользователь получает точное сообщение, а не общий текст «что-то пошло не так»

Как вывести текст ошибки

Для диагностики можно получить объект исключения:

try
{
    int number = Convert.ToInt32("abc");
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

В пользовательском интерфейсе не всегда стоит показывать технический текст ошибки. Но при разработке ex.Message помогает понять причину

finally

Блок finally выполняется всегда: была ошибка или нет

try
{
    Console.WriteLine("Пробуем выполнить код");
}
catch
{
    Console.WriteLine("Ошибка");
}
finally
{
    Console.WriteLine("Этот блок выполнится в любом случае");
}

finally часто используют для освобождения ресурсов, но в современном C# для файлов и подключений часто удобнее using

Когда лучше TryParse

Для обычной проверки ввода числа часто лучше использовать int.TryParse, а не try catch:

Console.Write("Введите число: ");
string? input = Console.ReadLine();

if (int.TryParse(input, out int number))
{
    Console.WriteLine($"Вы ввели {number}");
}
else
{
    Console.WriteLine("Это не число");
}

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

Частые ошибки

Писать пустой catch

Плохо:

catch
{
}

Так вы прячете ошибку и потом не понимаете, почему программа ведет себя странно

Ловить Exception везде подряд

catch (Exception) иногда нужен, но лучше ловить конкретные исключения, если вы понимаете возможную причину

Использовать try catch вместо нормальной проверки

Если можно заранее проверить условие, часто лучше проверить:

if (b != 0)
{
    Console.WriteLine(a / b);
}

Как логировать ошибку и показать нормальное сообщение

В реальной программе пользователю не всегда нужно видеть техническую ошибку. Лучше показать спокойное сообщение, а детали записать в лог:

try
{
    int number = Convert.ToInt32("abc");
}
catch (FormatException ex)
{
    Console.WriteLine("Введите число в правильном формате");
    File.WriteAllText("error.log", ex.ToString());
}

Пользователь увидит понятный текст, а разработчик сможет открыть error.log и посмотреть детали

Для такого примера в начале файла может понадобиться:

using System.IO;

В современных проектах using часто подключаются неявно, но в старых шаблонах его нужно добавить вручную

Когда ошибку нужно пробросить дальше

Иногда метод не должен сам решать, что делать с ошибкой. Тогда исключение можно поймать, добавить контекст и снова выбросить:

try
{
    // опасная операция
}
catch (Exception ex)
{
    Console.WriteLine($"Ошибка при обработке заказа: {ex.Message}");
    throw;
}

throw; сохраняет исходную информацию об ошибке. Это полезно, если выше по коду есть общий обработчик или логирование

Мини-задание

Сделайте программу, которая просит два числа и делит первое на второе. Обработайте:

  • ввод текста вместо числа;
  • деление на ноль;
  • успешный расчет.

Потом перепишите ввод через int.TryParse и сравните, какой вариант читается понятнее

Что почитать дальше по C#

Если нужен общий маршрут по теме, откройте рубрику C#. Для соседних задач пригодятся эти разборы:

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные

Настройки cookie

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x