Исключения
Исключения в C# на первый взгляд являются такими же, как в Java. Инструкции C# try- catch
и try-catch-finally
работают подобно своим аналогам в Java (смотрите раздел оthrows
, поэтому невозможно указать вызывающей стороне, что некоторый код в методе может порождать исключение. Также имеется try-finally
, который не подавляет порожденные исключения, но предлагает блок finally
, выполняющий после порождения исключения, чтобы произвести очистку.
Порождение исключений делается с помощью инструкции throw
. Например, чтобы породить SystemException
, используется код throw new SystemException (<arg- list>);
. Это полностью совпадает c тем, как исключения порождается в Java. Требуется только инструкция throws
и подходящий класс исключения. Далее представлен список некоторых стандартных классов исключений, предоставляемых средой выполнения .NET. Так же как в Java, их функциональность отражается в данных им именах:
□ Exception
— базовый класс для всех объектов исключений.
□ SystemException
— базовый класс для всех ошибок, создаваемых во время выполнения.
□ IndexOutOfRangeException
возникает, когда индекс массива во время выполнения оказывается вне границ заданного диапазона.
□ NullReferenceException
порождается, когда во время выполнения ссылаются на null
.
□ InvalidOperationException
порождается некоторыми методами, когда вызов метода бывает не действителен для текущего состояния объекта.
□ ArgumentException
— базовый класс всех исключений для аргументов.
□ ArgumentNullException
порождается если аргумент задан как null
, когда это недопустимо.
□ InteropException
является базовым классом для исключений, которые возникают или направлены на среды вне CLR.
Одним исключением, которое возникает независимо от того, будет ли оно специально порождаться или нет, является System.OverflowException
, связанное с вычисленными результатами, превосходящими диапазон значений типа данных переменной результата. Инструкции checked
и unchecked
могут инициировать или подавлять связанные с этим исключения. Дополнительная информация о checked
и unchecked
находится в разделе данного приложения о ключевых словах.
Условная компиляция
Препроцессор в C# эмулируется. Он выполняется как отдельный процесс, прежде чем компилятор начнет свою работу. Поддерживаемые здесь директивы больше всего соответствуют C++, чем какому-либо другому языку. Конечно, в Java не существует эквивалентов функциональности, описанных в этом разделе. Разрешается определять символы, которые проверяются с помощью простых условных директив. Те, которые оказываются true
, включаются и компилируются, иначе код игнорируется. Определение символа может происходить двумя способами. Прежде всего с использованием ключа компилятора /define
, за которым следует двоеточие и определяемый символ, например:
csc /define:TEST_TEST samples.cs
Можно также определить символы на странице конфигурационных свойств проекта, добавляя их в разделенный двоеточиями список констант условной компиляции. Или пойти программным путем, используя директиву #define
. В этом случае директива должна появиться раньше, чем что-либо другое, и применяется ко всем лексемам в области действия файла. Здесь перечислены допустимые условные директивы:
□ #if
используется для проверки существования символа
□ #elif
позволяет добавить несколько ветвей к инструкции #if
□ #else
предоставляет окончательное альтернативное условие для #if
и #elif
□ #endif
заканчивает инструкцию #if
namespace Samples {
using System;
#if EXAMPLE
public class Example {
public Example() {
}
}
#elif TEST_TEST
public class Test {
public Test() {
}
}
#else
public class None {
public None() {
}
}
#endif
}
Добавление инструкции #define TEST_TEST
делает класс Test
видимым для компиляции, a #define EXAMPLE
делает класс Example
видимым для компиляции. Если ничего не добавлять, то будет компилироваться класс None
. Для препроцессора C# доступны также две другие директивы — #warning
и #error
. Они должны помещаться в условное выражение #if
. Попробуйте добавить следующую строку под инструкцией #else
в приведенный код:
#warning I wouldn't try to instantiate the example object if I were you
C# также поддерживает условную функциональность. В коде ниже добавление условного атрибута в AMethod()
делает его компилируемым только в том случае, когда определен символ Test
:
[conditional('TEST_TEST')]
public void AMethod() {
string s = 'I am available only when Test is defined';
}
Вопросы безопасности