logo search
CSharp_Prog_Guide

Создание и генерация исключений

Исключения позволяют обозначить, что во время выполнения программы произошла ошибка. Объекты исключений, описывающие ошибку, создаются и затем генерируются с ключевым словом throw. Далее во время выполнения происходит поиск наиболее совместимого обработчика исключений.

Программисты должны генерировать исключения при выполнении одного или нескольких из следующих условий:

Например, если значение параметра метода является недопустимым:

static void CopyObject(SampleClass original)

{

if (original == null)

{

throw new System.ArgumentException("Parameter cannot be null", "original");

}

}

В качестве примера можно привести попытку записи в файл, доступный только для чтения. В случаях, когда состояние объекта не допускает выполнения операции, генерируется экземпляр InvalidOperationException или объекта на основе наследования этого класса. Далее показан пример метода, генерирующий объект InvalidOperationException:

----

In this case, the original exception should be caught and an ArgumentException instance should be created. The original exception should be passed to the constructor of the ArgumentException as the InnerException parameter:

static int GetValueFromArray(int[] array, int index)

{

try

{

return array[index];

}

catch (System.IndexOutOfRangeException ex)

{

System.ArgumentException argEx = new System.ArgumentException("Index is out of range", "index", ex);

throw argEx;

}

}

Exceptions contain a property named StackTrace. This string contains the name of the methods on the current call stack, together with the file name and line number where the exception was thrown for each method. A StackTrace object is created automatically by the common language runtime (CLR) from the point of the throw statement, so that exceptions must be thrown from the point where the stack trace should begin.

All exceptions contain a property named Message. This string should be set to explain the reason for the exception. Note that information that is sensitive to security should not be put in the message text. In addition to Message, ArgumentException contains a property named ParamName that should be set to the name of the argument that caused the exception to be thrown. In the case of a property setter, ParamName should be set to value.

Public and protected methods should throw exceptions whenever they cannot complete their intended function. The exception class that is thrown should be the most specific exception available that fits the error conditions. These exceptions should be documented as part of the class functionality, and derived classes or updates to the original class should retain the same behavior for backward compatibility.

В этом случае, должно быть перехвачено исходное исключение и создан экземпляр ArgumentException. Исходное исключение должно быть передано конструктору ArgumentException в качестве параметра InnerException:

----

Исключения содержат свойство с именем StackTrace. Строка содержит имена методов в текущем стеке вызовов вместе с именем файла и номером строки, в которой было сгенерировано исключение для каждого метода. Объект StackTrace создается автоматически средой CLR из точки оператора throw, так что исключения должны генерироваться из той точки, где должна начинаться трассировка стека.

Все исключения содержат свойство с именем Message. Эта строка должна содержать сообщение с объяснением причин исключения. Обратите внимание, что секретные сведения не следует помещать в текст сообщения. Кроме Message, ArgumentException содержит свойство с именем ParamName, которому необходимо присвоить имя аргумента, вызвавшего генерацию исключения. В случае с методом set свойств, свойству ParamName должно быть присвоено значение value.

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

Things to Avoid When Throwing Exceptions

The following list identifies practices to avoid when throwing exceptions:

Defining Exception Classes

Programs can throw a predefined exception class in the System namespace (except where previously noted), or create their own exception classes by deriving from ApplicationException. The derived classes should define at least four constructors: one default constructor, one that sets the message property, and one that sets both the Message and InnerException properties. The fourth constructor is used to serialize the exception. New exception classes should be serializable. For example:

[Serializable()]

public class InvalidDepartmentException : System.Exception

{

public InvalidDepartmentException() { }

public InvalidDepartmentException(string message) { }

public InvalidDepartmentException(string message, System.Exception inner) { }

// Constructor needed for serialization

// when exception propagates from a remoting server to the client.

protected InvalidDepartmentException(System.Runtime.Serialization.SerializationInfo info,

System.Runtime.Serialization.StreamingContext context) { }

}

New properties should only be added to the exception class when the data they provide is useful to resolving the exception. If new properties are added to the derived exception class, ToString() should be overridden to return the added information.