Поделиться через


Утверждения в управляемом коде

Оператор проверочного утверждения Assert проверяет выполнение условия, указанного в качестве аргумента для оператора Assert. Если условие выполняется, никаких действий не производится. Если же условие не выполняется, то утверждение выдает ошибку. При работе с отладочной сборкой выполнение программы приостанавливается.

В этом разделе

Проверочные утверждения в пространстве имен System.Diagnostics

Метод Debug.Assert

Побочные эффекты метода Debug.Assert

Требования к трассировке и отладке

Аргументы методов Assert

Настройка поведения проверочных утверждений

Использование проверочных утверждений в файлах конфигурации

Проверочные утверждения в пространстве имен System.Diagnostics

В Visual Basic и Visual C# можно использовать метод Assert из класса Debug или из класса Trace, которые принадлежат пространству имен System.Diagnostics. Методы класса Debug не включаются в окончательную версию (версию выпуска) программы, поэтому они не увеличивают ее размер и не уменьшают скорость ее выполнения.

C++ не поддерживает методы класса Debug. В случае C++ такого же результата можно добиться с помощью класса Trace в сочетании с условной компиляцией, например: #ifdef DEBUG... #endif.

Содержание раздела

Метод Debug.Assert

Метод Debug.Assert можно свободно использовать для проверки условий, которые должны выполняться, если код программы написан правильно. Предположим, что имеется функция целочисленного деления. По правилам математики делитель не может быть равен нулю. Проверить выполнение этого условия в имеющейся функции можно при помощи утверждения:

Function IntegerDivide(ByVal dividend As Integer, ByVal divisor As Integer) As Integer
    Debug.Assert(divisor <> 0)
    Return CInt(dividend / divisor)
End Function
int IntegerDivide ( int dividend , int divisor )
    { Debug.Assert ( divisor != 0 );
        return ( dividend / divisor ); }

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

Вот другой пример. Пусть имеется класс, описывающий текущий счет:

Dim amount, balance As Double
balance = savingsAccount.balance
Debug.Assert(amount <= balance)
SavingsAccount.Withdraw(amount)
float balance = savingsAccount.Balance;
Debug.Assert ( amount <= balance );
savingsAccount.Withdraw ( amount );

Прежде чем снять деньги со счета, необходимо удостовериться, что остаток на счете покрывает требуемую сумму. Для проверки остатка на счете можно написать проверочное утверждение:

Dim amount, balance As Double
balance = savingsAccount.balance
Trace.Assert(amount <= balance)
SavingsAccount.Withdraw(amount)
float balance = savingsAccount.Balance;
Trace.Assert ( amount <= balance );
savingsAccount.Withdraw ( amount );

Обратите внимание, что в версии для выпуска вызов метода Debug.Assert в коде будет отсутствовать. Это означает, что в версии для выпуска проверка остатка на счете производиться не будет. Чтобы решить эту проблему, следует поменять вызов метода Debug.Assert на вызов метода Trace.Assert, который не исчезнет в версии для выпуска:

Вызовы Trace.Assert создают дополнительную нагрузку в версии выпуска, в отличие от вызовов Debug.Assert.

Содержание раздела

Побочные эффекты метода Debug.Assert

При использовании метода Debug.Assert необходимо убедиться, что код внутри Assert не изменит результатов работы программы, если удалить Assert. В противном случае может быть создана ошибка, которая проявится только в версии программы для выпуска. Особая осторожность необходима в случае, если проверочное утверждение содержит вызовы функций или процедур, пример которых показан ниже:

' unsafe code
Debug.Assert (meas(i) <> 0 )
// unsafe code
Debug.Assert (meas(i) != 0 );

Такое использование метода Debug.Assert на первый взгляд может показаться безопасным, но предположим, например, что функция meas обновляет счетчик при каждом вызове. При сборке версии для выпуска вызов функции meas исчезнет, а значит, счетчик обновляться не будет. Это и есть пример функции, имеющей побочный эффект. Удаление вызова функции, имеющей побочные эффекты, может создать ошибку, которая проявится только в версии программы для выпуска. Чтобы избежать подобных проблем, не следует помещать вызовы функций в оператор метода Debug.Assert. Вместо этого следует использовать временную переменную:

temp = meas( i )
Debug.Assert (temp <> 0)
temp = meas( i );
Debug.Assert ( temp != 0 );

Даже при использовании метода Trace.Assert рекомендуется избегать размещения вызовов функций в операторе Assert. Такие вызовы, в принципе, безопасны, поскольку операторы Trace.Assert сохраняются в выпускной сборке. Однако, если взять за правило не использовать подобные конструкции, это снизит вероятность ошибки при использовании метода Debug.Assert.

Содержание раздела

Требования к трассировке и отладке

Если проект создается с помощью мастеров Visual Studio, символ TRACE определяется по умолчанию и в конфигурации выпуска, и в конфигурации отладки. Символ DEBUG определяется по умолчанию только в отладочной сборке.

Иначе для работы методов Trace требуется наличие одной из следующих строк в самом начале исходного файла:

  • #Const TRACE = True — в Visual Basic

  • #define TRACE — в Visual C# и C++

Либо, как вариант, построение программы должно выполняться с параметром TRACE:

  • /d:TRACE=True — в Visual Basic

  • /d:TRACE — в Visual C# и C++

Если методы Debug требуется использовать в выпускной сборке программы на языках C# или Visual Basic, необходимо определить символ DEBUG в конфигурации выпуска.

C++ не поддерживает методы класса Debug. В случае C++ такого же результата можно добиться с помощью класса Trace в сочетании с условной компиляцией, например: #ifdef DEBUG... #endif. Эти символы можно задать в диалоговом окне <Проект> Страницы свойств. Дополнительные сведения см. в разделе Изменение параметров проекта для конфигурации отладки в Visual Basic или Изменение параметров проекта для конфигурации отладки в C или C++.

Аргументы методов Assert

Методы Trace.Assert и Debug.Assert принимают до трех аргументов. Первый аргумент является обязательным и задает условие, которое требуется проверить. Если вызвать метод Trace.Assert(Boolean) или Debug.Assert(Boolean) только с одним аргументом, то метод Assert проверит условие и, если оно ложно, выведет содержимое стека вызовов в окно Вывод. В следующем примере показаны методы Trace.Assert(Boolean) и Debug.Assert(Boolean):

Debug.Assert(stacksize > 0)
Trace.Assert(stacksize > 0)
Debug.Assert ( stacksize > 0 );
Trace.Assert ( stacksize > 0 ); 

Второй и третий аргументы, если они присутствуют, должны иметь строковый формат. Если метод Trace.Assert или Debug.Assert вызывается с двумя или тремя аргументами, первым аргументом является условие. Метод проверяет условие и, если результат ложен, выводит вторую и третью строки. Ниже показаны примеры использования методов Debug.Assert(Boolean, String) и Trace.Assert(Boolean, String) с двумя аргументами:

Debug.Assert(stacksize > 0, "Out of stack space")
Trace.Assert(stacksize > 0, "Out of stack space")
Debug.Assert ( stacksize > 0, "Out of stack space" );
Trace.Assert ( stacksize > 0, "Out of stack space" );

В следующем примере показаны методы Assert и Assert:

Debug.Assert(stacksize > 0, "Out of stack space. Bytes left:" , Format(size, "G"))
Trace.Assert(stacksize > 0, "Out of stack space. Bytes left:" , Format(size, "G"))
Trace.Assert(stacksize > 0, "Out of stack space. Bytes left:", "inctemp failed on third call" )
Debug.Assert ( stacksize > 100, "Out of stack space" , "Failed in inctemp" );
Trace.Assert ( stacksize > 0, "Out of stack space", "Failed in inctemp" ); 

Содержание раздела

Настройка поведения проверочных утверждений

Если приложение работает в режиме пользовательского интерфейса, метод Assert отображает диалоговое окно Ошибка в утверждении, если условие не выполняется. Действия, выполняемые при ошибке утверждения, определяются свойствами Listeners и Listeners, соответственно.

Можно настроить поведение при выводе отладочного сообщения путем добавления объекта TraceListener к коллекции Listeners, удаления TraceListener из коллекции Listeners или переопределения метода TraceListener.Fail существующего объекта TraceListener для изменения его поведения.

Например, можно переопределить метод TraceListener.Fail таким образом, чтобы вместо отображения диалогового окна Ошибка в утверждении производилась запись в журнал событий.

Чтобы можно было настроить поведение программы таким образом, в программе должен быть прослушиватель, причем унаследованный от класса TraceListener и с переопределенным методом TraceListener.Fail.

Дополнительные сведения см. в разделе Прослушиватели трассировки.

Содержание раздела

Использование проверочных утверждений в файлах конфигурации

Проверочные утверждения можно использовать в файле конфигурации программы, так же как и в коде. Дополнительные сведения см. в разделе Trace.Assert или Debug.Assert.

См. также

Задачи

Практическое руководство. Условная компиляция с использованием атрибутов Trace и Debug

Ссылки

Debug.Assert

Trace.Assert

Основные понятия

Безопасность отладчика

Другие ресурсы

Трассировка и оборудование приложений

Подготовка к отладке: типы проектов C#, F# и Visual Basic

Отладка управляемого кода