English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Здесь вы узнаете, как обрабатывать исключительные ситуации в C# с использованием блоков try, catch и finally.
Необходимо обрабатывать исключительные ситуации в приложениях, чтобы предотвратить аварийное завершение работы программы и неожиданные результаты, записывать исключительные ситуации и продолжать выполнение других функций. C# предоставляет встроенную поддержку обработки исключительных ситуаций с использованием блоков try, catch и finally.
Грамматика: }}
try { // Код, который может вызвать исключение, должен быть放在 здесь } catch { // Обработка исключений здесь } finally { // Финальная очистка кода }
Блок try:Любой код, который может вызвать исключение, должен быть поместен в блок try{ }. Если в процессе выполнения произойдет исключение, управление потоком будет передано в первый соответствующий блок catch.
catch Блок:Блок catch является блоком обработки исключений, в котором можно выполнить某些 действия, такие как запись и аудит исключений. Блок catch принимает параметр типа исключения, с помощью которого можно получить подробную информацию о排斥ении.
finally Блок:finally всегда будет выполняться, независимо от того, произошло ли исключение или нет. Обычно finally должен использоваться для освобождения ресурсов, таких как закрытие потоков или файлов, открытых в блоке try.
Если вы введете символьный carácter, который не является числом, это может вызвать исключение.
class Program { static void Main(string[] args) { Console.WriteLine("Введите число: "); var num = int.Parse(Console.ReadLine()); Console.WriteLine($"Квадрат {num} равен {num * num}"); } }
Чтобы обработать возможные исключения в примере выше, заключите код в блок try, а затем обработайте исключение в блоке catch, как показано ниже.
class Program { static void Main(string[] args) { try { Console.WriteLine("Введите число: "); var num = int.parse(Console.ReadLine()); Console.WriteLine($"Квадрат {num} равен {num * num}"); } catch { Console.Write("Произошла ошибка."); } finally { Console.Write("Перепробуйте с другим числом."); } } }
В примере выше мы заключаем этот код в блок try. Если в блоке try произойдет исключение, программа перейдет к блоку catch. В блоке catch мы будем отображать сообщение, информирующее пользователя о его ошибке, а в блоке finally - сообщение о действиях, выполняемых после выполнения программы.
Блок try должен следовать за catch или finally или обоими блоками. В противном случае, использование блока catch или блока finally без блока try приведет к компиляционной ошибке.
В идеале, блок catch должен содержать параметры встроенных или пользовательских классов исключений для получения подробной информации об ошибке. Включен параметр type для捕获所有类型的 исключений Exception.
class Program { static void Main(string[] args) { try { Console.WriteLine("Введите число: "); var num = int.parse(Console.ReadLine()); Console.WriteLine($"Квадрат {num} равен {num * num}"); } catch(Exception ex) { Console.Write("Информация об ошибке:" + ex.Message); } finally { Console.Write("Перепробуйте с другим числом."); } } }
Вы можете использовать несколько блоков catch с различными параметрами типа исключения. Это называется фильтром исключений. Фильтр исключений полезен, когда вы хотите обрабатывать различные типы исключений по-разному.
class Program { static void Main(string[] args) { Console.Write("Пожалуйста, введите число для деления 100: "); try { int num = int.Parse(Console.ReadLine()); int result = 100 / num; Console.WriteLine("100 / {0} = {1}", num, result); } catch(DivideByZeroException ex) { Console.Write("Не можно делить на ноль. Пожалуйста, попробуйте еще раз."); } catch(InvalidOperationException ex) { Console.Write("Невалидное действие. Пожалуйста, попробуйте еще раз."); } catch(FormatException ex) { Console.Write("Неvalidный формат. Пожалуйста, попробуйте еще раз."); } catch(Exception ex) { Console.Write("Произошла ошибка! Пожалуйста, попробуйте еще раз."); } } }
В примере выше мы указали несколько блоков catch с различными типами исключений. Мы можем отображать пользователю соответствующие сообщения об ошибках, чтобы пользователь не повторял одну и ту же ошибку.
В одном блоке try..catch не разрешается использовать блок catch без параметров и блок catch с параметром Exception, так как они выполняют одинаковые действия.
try { // Код, который может вызвать исключение } catch // не может быть одновременно catch и catch(Exception исключение) { Console.WriteLine("Произошла исключительная ситуация"); } catch(Exception ex) // не может быть одновременно catch и catch(исключение исключение) { Console.WriteLine("Произошла исключительная ситуация"); }
Кроме того, блок catch без параметров catch {} или общеприменимый блок catch (Exception ex){} должен быть последним. Если после блока catch {} или блока catch (Exception ex) есть другие блоки catch, компилятор выдаст ошибку.
Пример: недопустимый блок catch
try { // Код, который может вызвать исключение } catch { // Этот блок catch должен быть последним } catch (NullReferenceException nullEx) { Console.WriteLine(nullEx.Message); } catch (InvalidCastException inEx) { Console.WriteLine(inEx.Message); }
Блок finally является опционным и должен следовать за блоком try или catch. Блок finally всегда будет выполняться независимо от того, произошел ли исключение или нет. Блок finally обычно используется для выполнения кода очистки, например, для обработки неуправляемых объектов.
Пример: блок finally
static void Main(string[] args) { FileInfo file = null; try { Console.Write("Введите имя файла для записи: "); string fileName = Console.ReadLine(); file = new FileInfo(fileName); file.AppendText("Hello World!"); } catch(Exception ex) { Console.WriteLine("Произошла ошибка: {0}", ex.Message); } finally { // Здесь нужно очистить объект файла; file = null; } }
finally не может использоваться Множественные блоки. Кроме того, блок finally не может содержать ключевые слова return, continue или break. Он не позволяет контролю выйти из блока finally.
C# позволяет использовать вложенные блоки try-catch. При использовании вложенных блоков try-catch исключение будет перехвачено в первом соответствующем блоке catch после блока try, где произошел исключение.
static void Main(string[] args) { var divider = 0; try { try { var result = 100 / divider; } catch { Console.WriteLine("Внутренний catch"); } } catch { Console.WriteLine("Внешний catch"); } }
Внутренний catch
catch в приведенном выше примере выполнит внутренний блок, так как он является первым блоком, который обрабатывает все типы исключений.
Если внутренний блок catch не найдет соответствующий тип выброшенного исключения, управление перейдет к внешнему блоку catch, пока не будет найден подходящий фильтр исключений. См. следующий пример.
static void Main(string[] args) { var divider = 0; try { try { var result = 100 / divider; } catch(NullReferenceException ex) { Console.WriteLine("Внутренний catch"); } } catch { Console.WriteLine("Внешний catch"); } }
Внешний catch
В примере выше вызывается исключение DivideByZeroException. Поскольку внутренний блок catch обрабатывает только NullReferenceTypeException, оно будет обработано внешним блоком catch.