Что такое исключения в C# и как работать с блоками try, catch и finally
Обработка исключений — способ предотвратить ошибки в исполнении программы. Чтобы обработать Exception
(исключение) в языке C# используют операторы try
, catch
и finally
.
Содержание статьи:
2. Try, catch, finally и throw: сновные команды в С#
3. Exception: типы исключений в C#
4. Пример c try и catch в C# (example)
5. Алгоритм выполнения операторов try, catch и finally в C#
6. Ошибки в приложениях с визуальным интерфейсом
7. Генерирование исключительных ситуаций
8. Фильтры и условные конструкции
Часто во время выполнения программ возникают ошибки, которые не связаны с плохим написанием кода. Например, программе нужно найти пользователя, который отсутствует в базе данных, или подключенный файл оказался поврежденным.
Некоторые из ошибок происходят случайным образом и их невозможно предвидеть. Их называют исключениями.
Исключения позволяют программе передавать управление между частями кода, «пропуская» ошибку выполнения программы. Для этого в C# существуют команды try
, catch
, finally
, а также throw
:
try
применяют для инкапсуляции. В него помещают так называемый «ненадежный» код, который может выдать ошибку. Там могут содержаться вызовы методов, обращения к интерфейсам, операторы цикла. В случае, если некая строка из этого блока выдает исключение, то он обрабатывается в блоке catch
.catch
. Здесь исключение можно обработать. Варианты обработки зависят от задач разработчиков и типа ошибки. Например, записать ошибку в лог, завершить работу скрипта или прописать выдачу конкретного сообщения. В случае, если блок catch
пустой, программа пропустит исключение.finally
— выполнить определенный код вне зависимости от того, сработало исключение или нет. Это может быть, к примеру, освобождение объекта из памяти. Иногда блок finally
не обязателен и опускается. Так происходит, когда обработка исключения предусматривает, что программа дальше будет выполняться.throw
.При работе с ошибками в C# используют тип исключения Exception
. Он базовый и включает все исключения. У него есть несколько свойств, с помощью которых можно получить сведения об исключении. Например, определить расположение, причину исключения, тип.
В таблице ниже перечислим несколько свойств.
Свойство | Функция |
InnerException | Выдача экземпляра класса, вызвавшего исключение |
Source | Указание на имя объекта, который вызвал исключение |
Message | Текст ошибки |
HelpLink | Ссылка на файл справки, связанный с исключениями. |
Если нужно обработать только определенные ошибки, используют конкретный тип исключений.
Давайте рассмотрим несколько наиболее популярных.
Тип исключения | Значение |
ArgumenOutOfRangeException | Значение аргумента не соответствует допустимому диапазону |
IndexOutOfRangeException | Выход за диапазон массива или допустимых значений |
StackOverflowException | Переполнение стека |
OutOfMemoryException | Недостаточно памяти для выполнения программы |
NullReferenceException | Обращение к неопределенному объекту |
Вот пример обработки исключения типа IndexOutOfRangeException
с операторами try
и catch
в C#:
// Exception handling of above code // using try catch blocks using System; class Program : System.Exception { static void Main(string[] args) { // Declare an array of max index 4 int[] arr = { 1, 2, 3, 4, 5 }; // Display values of array elements for (int i = 0; i < arr.Length; i++) { Console.WriteLine(arr[i]); } try { // Try to access invalid index of array Console.WriteLine(arr[7]); // An exception is thrown upon executing // the above line } catch (IndexOutOfRangeException e) { // The Message property of the object // of type IndexOutOfRangeException // is used to display the type of exception // that has occurred to the user. Console.WriteLine("An Exception has occurred : {0}", e.Message); } }
Обработку разных типов можно разграничить. Для этого каждый тип прописывают в отдельном блоке catch
. Здесь важно помнить о приоритетности выполнения, так как предложения catch
будут срабатывать в порядке написания.
Если менее конкретные исключения будут записаны перед более конкретными, то компилятор может выдать ошибку из-за невозможности достигнуть следующего блока.
Пример многоразового использования блока catch
в C#:
// C# Program to show use of // multiple try catch blocks using System; class Program { static void Main(string[] args) { int[] arr = {19, 0, 75, 52}; try { // Try to generate an exception for (int i = 0; i < arr.Length; i++) { Console.WriteLine(arr[i] / arr[i + 1]); } } // Catch block for invalid array access catch (IndexOutOfRangeException e) { Console.WriteLine("An Exception has occurred : {0}", e.Message); } // Catch block for attempt to divide by zero catch (DivideByZeroException e) { Console.WriteLine("An Exception has occurred : {0}", e.Message); } // Catch block for value being out of range catch (ArgumentOutOfRangeException e) { Console.WriteLine("An Exception has occurred : {0}", e.Message); } // Finally block // Will execute irrespective of the above catch blocks finally { for (int i = 0; i < arr.Length; i++) { Console.Write(" {0}", arr[i]); } } } }
Используя блоки try
, catch
и finally
сначала выполняются команды в блоке try
. Когда исключений нет, программа сразу переходит к блоку finally
(если он есть) и часть программы, которая отвечает за обработку исключений, завершается.
Когда в блоке try
произошла ошибка, то выполнение программы приостанавливается, а общеязыковая исполняющая среда (CLR) производит поиск блока catch
. Если блок найден, то после его выполнения идет блок finally
. В другом случае программа аварийно завершит работу.
Например, в случае деления на 0, возникает исключение System.DivideByZeroException
. Чтобы не возникало таких ошибок, в блоке catch
прописываем инструкцию, как указано в примере кода. Алгоритм не будет делить на 0 и выводить результаты, а программа аварийно завершается.
Теперь давайте посмотрим поближе на пример использования try
и catch
в C#:
//C#: Exception Handling using System; class MyClient { public static void Main() { int x = 0; int div = 0; try { div = 100 / x; Console.WriteLine("This linein not executed"); } catch (DivideByZeroException) { Console.WriteLine("Exception occured"); } Console.WriteLine($"Result is {div}"); } }
Все вышеуказанные правила работают в консольных приложениях. Если в программы есть интерфейс, то при возникновении ошибки увидим соответствующее окно:
Пример ошибки в Microsoft Visual Studio
В таком случае разработчик может попробовать продолжить выполнение программы, прервать его или изменить настройки и обработать исключение.
В некоторых очевидных ситуациях (таких, как деление на 0) C# самостоятельно сгенерирует исключение. Чтобы создать персональное исключение, применяют оператор throw
. Использование собственного класса исключений ограничивается лишь фантазией разработчика.
Например, у нас есть платформа для разработки ASP.NET. Платформа должна разрешать пользователю иметь только один сеанс в системе и выдавать сообщение об ошибке, если он вошел с другого окна браузера.
Пример решения:
namespace ExceptionHandlingDemo { //Creating our own Exception Class by inheriting Exception class public class OddNumberException : Exception { //Overriding the Message property public override string Message { get { return "divisor cannot be odd number"; } } } class Program { static void Main(string[] args) { int x, y, z; Console.WriteLine("ENTER TWO INTEGER NUMBERS:"); x = int.Parse(Console.ReadLine()); y = int.Parse(Console.ReadLine()); try { if (y % 2 > 0) { //OddNumberException ONE = new OddNumberException(); //throw ONE; throw new OddNumberException(); } z = x / y; Console.WriteLine(z); } catch (OddNumberException one) { Console.WriteLine(one.Message); } Console.WriteLine("End of the program"); Console.ReadKey(); } } }
Применять блоки try
, catch
и finnaly
в C# требует больших производительных ресурсов, и это не всегда необходимо. Иногда лучше применить условные конструкции. Например, программа запрашивает ввод числа, а вместо этого пользователь использовал число прописью (строку). В таком случае лучше использовать преобразование типов.
Метод Int32.TryParse
выдаст значение true
, если тип возможно преобразовать. Таким образом для этого типа ошибок необязательно применять try
/ catch
.
Блок catch
тоже можно реализовать по-разному. Наиболее простой способ в C# — обрабатывать любое исключение (тип Exceptions
). Но разработчикам все же советуют перехватывать только те исключения, которые они смогут восстановить. Также в C# есть возможность настроить обработку исключений только при конкретных условиях. После выражения catch
используют оператор when
, где указывают условие. Обработка будет происходить только в случае, если значение в условии истинное.
Реализовать обработку исключений в C# можно разными способами. Некоторые распространенные ошибки возможно уловить с помощью стандартных типов исключений. Нужно понимать свойства ошибок, чтобы учиться с ними работать. Также важно учитывать последовательность исключений.
Помните, что в случае, если C# не имеет функционала для предотвращения такого исключения, его можно создать самостоятельно.
Видео: обработка исключений в языке программирования C#
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…
Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…