Что такое исключения в 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. Фильтры и условные конструкции
Вступление
Часто во время выполнения программ возникают ошибки, которые не связаны с плохим написанием кода. Например, программе нужно найти пользователя, который отсутствует в базе данных, или подключенный файл оказался поврежденным.
Некоторые из ошибок происходят случайным образом и их невозможно предвидеть. Их называют исключениями.
Try, catch, finally и throw: основные команды в С#
Исключения позволяют программе передавать управление между частями кода, «пропуская» ошибку выполнения программы. Для этого в C# существуют команды try, catch, finally, а также throw:
- Блок
tryприменяют для инкапсуляции. В него помещают так называемый «ненадежный» код, который может выдать ошибку. Там могут содержаться вызовы методов, обращения к интерфейсам, операторы цикла. В случае, если некая строка из этого блока выдает исключение, то он обрабатывается в блокеcatch. - Когда происходит исключение, запускается блок
catch. Здесь исключение можно обработать. Варианты обработки зависят от задач разработчиков и типа ошибки. Например, записать ошибку в лог, завершить работу скрипта или прописать выдачу конкретного сообщения. В случае, если блокcatchпустой, программа пропустит исключение. - Задача блока
finally— выполнить определенный код вне зависимости от того, сработало исключение или нет. Это может быть, к примеру, освобождение объекта из памяти. Иногда блокfinallyне обязателен и опускается. Так происходит, когда обработка исключения предусматривает, что программа дальше будет выполняться. - В языке C# существует несколько стандартных типов исключений, но есть возможность создавать их самостоятельно. Для этого используют оператор
throw.
Exception: типы исключений в C#
При работе с ошибками в C# используют тип исключения Exception. Он базовый и включает все исключения. У него есть несколько свойств, с помощью которых можно получить сведения об исключении. Например, определить расположение, причину исключения, тип.
В таблице ниже перечислим несколько свойств.
| Свойство | Функция |
InnerException |
Выдача экземпляра класса, вызвавшего исключение |
Source |
Указание на имя объекта, который вызвал исключение |
Message |
Текст ошибки |
HelpLink |
Ссылка на файл справки, связанный с исключениями. |
Если нужно обработать только определенные ошибки, используют конкретный тип исключений.
Давайте рассмотрим несколько наиболее популярных.
| Тип исключения | Значение |
ArgumenOutOfRangeException |
Значение аргумента не соответствует допустимому диапазону |
IndexOutOfRangeException |
Выход за диапазон массива или допустимых значений |
StackOverflowException |
Переполнение стека |
OutOfMemoryException |
Недостаточно памяти для выполнения программы |
NullReferenceException |
Обращение к неопределенному объекту |
Пример c try и catch в C# (example)
Вот пример обработки исключения типа 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 в C#
Используя блоки 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# не имеет функционала для предотвращения такого исключения, его можно создать самостоятельно.
https://www.youtube.com/watch?v=A0lccpS6P8s
Видео: обработка исключений в языке программирования C#

Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: