Виды ошибок си шарп

Виды ошибок си шарп

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

  • InnerException : хранит информацию об исключении, которое послужило причиной текущего исключения
  • Message : хранит сообщение об исключении, текст ошибки
  • Source : хранит имя объекта или сборки, которое вызвало исключение
  • StackTrace : возвращает строковое представление стека вызывов, которые привели к возникновению исключения
  • TargetSite : возвращает метод, в котором и было вызвано исключение

Например, обработаем исключения типа Exception:

try < int x = 5; int y = x / 0; Console.WriteLine($"Результат: "); > catch (Exception ex) < Console.WriteLine($"Исключение: "); Console.WriteLine($"Метод: "); Console.WriteLine($"Трассировка стека: "); >

Обработка исключений и класс Exception в C#

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

Но также есть более специализированные типы исключений, которые предназначены для обработки каких-то определенных видов исключений. Их довольно много, я приведу лишь некоторые:

  • DivideByZeroException : представляет исключение, которое генерируется при делении на ноль
  • ArgumentOutOfRangeException : генерируется, если значение аргумента находится вне диапазона допустимых значений
  • ArgumentException : генерируется, если в метод для параметра передается некорректное значение
  • IndexOutOfRangeException : генерируется, если индекс элемента массива или коллекции находится вне диапазона допустимых значений
  • InvalidCastException : генерируется при попытке произвести недопустимые преобразования типов
  • NullReferenceException : генерируется при попытке обращения к объекту, который равен null (то есть по сути неопределен)

И при необходимости мы можем разграничить обработку различных типов исключений, включив дополнительные блоки catch:

static void Main(string[] args) < try < int[] numbers = new int[4]; numbers[7] = 9; // IndexOutOfRangeException int x = 5; int y = x / 0; // DivideByZeroException Console.WriteLine($"Результат: "); > catch (DivideByZeroException) < Console.WriteLine("Возникло исключение DivideByZeroException"); >catch (IndexOutOfRangeException ex) < Console.WriteLine(ex.Message); >Console.Read(); >

В данном случае блоки catch обрабатывают исключения типов IndexOutOfRangeException и DivideByZeroException. Когда в блоке try возникнет исключение, то CLR будет искать нужный блок catch для обработки исключения. Так, в данном случае на строке

происходит обращение к 7-му элементу массива. Однако поскольку в массиве только 4 элемента, то мы получим исключение типа IndexOutOfRangeException. CLR найдет блок catch, который обрабатывает данное исключение, и передаст ему управление.

Следует отметить, что в данном случае в блоке try есть ситуация для генерации второго исключения — деление на ноль. Однако поскольку после генерации IndexOutOfRangeException управление переходит в соответствующий блок catch, то деление на ноль int y = x / 0 в принципе не будет выполняться, поэтому исключение типа DivideByZeroException никогда не будет сгенерировано.

Однако рассмотрим другую ситуацию:

try < object obj = "you"; int num = (int)obj; // System.InvalidCastException Console.WriteLine($"Результат: "); > catch (DivideByZeroException) < Console.WriteLine("Возникло исключение DivideByZeroException"); >catch (IndexOutOfRangeException)

В данном случае в блоке try генерируется исключение типа InvalidCastException, однако соответствующего блока catch для обработки данного исключения нет. Поэтому программа аварийно завершит свое выполнение.

Мы также можем определить для InvalidCastException свой блок catch, однако суть в том, что теоретически в коде могут быть сгенерированы самые разные типы исключений. А определять для всех типов исключений блоки catch, если обработка исключений однотипна, не имеет смысла. И в этом случае мы можем определить блок catch для базового типа Exception:

try < object obj = "you"; int num = (int)obj; // System.InvalidCastException Console.WriteLine($"Результат: "); > catch (DivideByZeroException) < Console.WriteLine("Возникло исключение DivideByZeroException"); >catch (IndexOutOfRangeException) < Console.WriteLine("Возникло исключение IndexOutOfRangeException"); >catch (Exception ex) < Console.WriteLine($"Исключение: "); >

И в данном случае блок catch (Exception ex)<> будет обрабатывать все исключения кроме DivideByZeroException и IndexOutOfRangeException. При этом блоки catch для более общих, более базовых исключений следует помещать в конце — после блоков catch для более конкретный, специализированных типов. Так как CLR выбирает для обработки исключения первый блок catch, который соответствует типу сгенерированного исключения. Поэтому в данном случае сначала обрабатывается исключение DivideByZeroException и IndexOutOfRangeException, и только потом Exception (так как DivideByZeroException и IndexOutOfRangeException наследуется от класса Exception).

Читайте также:  Скрытое поле

Источник

21 Exceptions

Exceptions in C# provide a structured, uniform, and type-safe way of handling both system level and application-level error conditions.

21.2 Causes of exceptions

Exception can be thrown in two different ways.

  • A throw statement (§13.10.6) throws an exception immediately and unconditionally. Control never reaches the statement immediately following the throw .
  • Certain exceptional conditions that arise during the processing of C# statements and expression cause an exception in certain circumstances when the operation cannot be completed normally. See §21.5 for a list of the various exceptions that can occur in this way.

Example: An integer division operation (§12.10.3) throws a System.DivideByZeroException if the denominator is zero. end example

21.3 The System.Exception class

The System.Exception class is the base type of all exceptions. This class has a few notable properties that all exceptions share:

  • Message is a read-only property of type string that contains a human-readable description of the reason for the exception.
  • InnerException is a read-only property of type Exception . If its value is non- null , it refers to the exception that caused the current exception. (That is, the current exception was raised in a catch block handling the InnerException .) Otherwise, its value is null , indicating that this exception was not caused by another exception. The number of exception objects chained together in this manner can be arbitrary.

The value of these properties can be specified in calls to the instance constructor for System.Exception .

21.4 How exceptions are handled

Exceptions are handled by a try statement (§13.11).

When an exception occurs, the system searches for the nearest catch clause that can handle the exception, as determined by the run-time type of the exception. First, the current method is searched for a lexically enclosing try statement, and the associated catch clauses of the try statement are considered in order. If that fails, the method that called the current method is searched for a lexically enclosing try statement that encloses the point of the call to the current method. This search continues until a catch clause is found that can handle the current exception, by naming an exception class that is of the same class, or a base class, of the run-time type of the exception being thrown. A catch clause that doesn’t name an exception class can handle any exception.

Once a matching catch clause is found, the system prepares to transfer control to the first statement of the catch clause. Before execution of the catch clause begins, the system first executes, in order, any finally clauses that were associated with try statements more nested that than the one that caught the exception.

If no matching catch clause is found:

  • If the search for a matching catch clause reaches a static constructor (§15.12) or static field initializer, then a System.TypeInitializationException is thrown at the point that triggered the invocation of the static constructor. The inner exception of the System.TypeInitializationException contains the exception that was originally thrown.
  • Otherwise, if an exception occurs during finalizer execution, and that exception is not caught, then the behavior is unspecified.
  • Otherwise, if the search for matching catch clauses reaches the code that initially started the thread, then execution of the thread is terminated. The impact of such termination is implementation-defined.

21.5 Common exception classes

The following exceptions are thrown by certain C# operations.

Exception Type Description
System.ArithmeticException A base class for exceptions that occur during arithmetic operations, such as System.DivideByZeroException and System.OverflowException .
System.ArrayTypeMismatchException Thrown when a store into an array fails because the type of the stored element is incompatible with the type of the array.
System.DivideByZeroException Thrown when an attempt to divide an integral value by zero occurs.
System.IndexOutOfRangeException Thrown when an attempt to index an array via an index that is less than zero or outside the bounds of the array.
System.InvalidCastException Thrown when an explicit conversion from a base type or interface to a derived type fails at run-time.
System.NullReferenceException Thrown when a null reference is used in a way that causes the referenced object to be required.
System.OutOfMemoryException Thrown when an attempt to allocate memory (via new ) fails.
System.OverflowException Thrown when an arithmetic operation in a checked context overflows.
System.StackOverflowException Thrown when the execution stack is exhausted by having too many pending calls; typically indicative of very deep or unbounded recursion.
System.TypeInitializationException Thrown when a static constructor or static field initializer throws an exception, and no catch clause exists to catch it.

Feedback

Submit and view feedback for

Источник

Исключения и обработка исключений

Функции обработки исключений в языке C# помогают вам справиться с непредвиденными или исключительными проблемами, которые возникают при выполнении программы. При обработке исключений используются ключевые слова try , catch и finally для действий, которые могут оказаться неудачными. Это позволяет обрабатывать ошибки так, как кажется разумным, а также правильно высвобождать ресурсы. Исключения могут создаваться средой выполнения (CLR), платформой .NET , библиотеками сторонних поставщиков или кодом самого приложения. Чтобы создать исключение, используйте ключевое слово throw .

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

В этом примере метод выполняет проверку деления на нуль и перехватывает ошибку. Если не использовать обработку исключений, такая программа завершит работу с ошибкой DivideByZeroException was unhandled (Исключение DivideByZero не обработано).

public class ExceptionTest < static double SafeDivision(double x, double y) < if (y == 0) throw new DivideByZeroException(); return x / y; >public static void Main() < // Input for test purposes. Change the values to see // exception handling behavior. double a = 98, b = 0; double result; try < result = SafeDivision(a, b); Console.WriteLine("divided by = ", a, b, result); > catch (DivideByZeroException) < Console.WriteLine("Attempted divide by zero."); >> > 

Общие сведения об исключениях

Исключения имеют следующие свойства.

  • Исключения представляют собой типы, производные в конечном счете от System.Exception .
  • Используйте блок try для выполнения таких инструкций, которые могут создавать исключения.
  • Когда внутри такого блока try возникает исключение, поток управления переходит к первому подходящему обработчику исключений в стеке вызовов. В C# ключевое слово catch обозначает обработчик исключений.
  • Если для созданного исключения не существует обработчиков, выполнение программы прекращается с сообщением об ошибке.
  • Не перехватывайте исключение, если вы не намерены его обрабатывать с сохранением известного состояния приложения. Если вы перехватываете System.Exception , создайте его заново в конце блока catch , используя ключевое слово throw .
  • Если блок catch определяет переменную исключения, ее можно использовать для получения дополнительных сведений о типе созданного исключения.
  • Программа может явным образом создавать исключения с помощью ключевого слова throw .
  • Объекты исключения содержат подробные сведения об ошибке, например состояние стека вызовов и текстовое описание ошибки.
  • Код в блоке finally выполняется, даже если создано исключение. Используйте блок finally , чтобы высвободить ресурсы, например закрыть потоки и файлы, которые были открыты внутри блока try .
  • Управляемые исключения реализованы в платформе .NET на основе структурированного механизма обработки исключений Win32. Дополнительные сведения см. в статьях Structured Exception Handling (C/C++) (Структурированная обработка исключений в C и C++) и A Crash Course on the Depths of Win32 Structured Exception Handling (Интенсивное погружение в структурированную обработку исключений на платформе Win32).

Спецификация языка C#

Дополнительные сведения см. в разделе Исключения в Спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.

Источник

Оцените статью