Что делает метод Assert ()? Это все еще полезно?

156

Я отлаживаю с контрольными точками, и я понимаю вызов assert? Я думал, что это только для модульных тестов. Что это делает больше, чем точка останова? Поскольку я могу использовать точку останова, зачем мне использовать Assert?

Pokus
источник
9
Кстати, если вы заинтересованы в утверждениях, вы должны обязательно углубиться в кодовые контракты .
MasterMastic
Возможный дубликат stackoverflow.com/questions/129120/…
Майкл Фрейдгейм

Ответы:

200

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

Если вы компилируете в Release, все Debug.Assertавтоматически пропускается.

Патрик Дежарден
источник
12
Как я могу получить такое же поведение Debug.Assert в режиме выпуска?
Хэмиш Грубиджан
15
Trace.Assert для режима выпуска, по-видимому, ссылается на : msdn.microsoft.com/en-us/library/… msdn.microsoft.com/en-us/library/e63efys0.aspx
Тим Абелл,
8
@HamishGrubijan А зачем вам Debug.Assertв режиме релиза?
Камило Мартин
25
IMO, исключение утверждений из кода выпуска похоже на проведение тренировок спасательной шлюпки в доке, а затем оставление спасательных шлюпок во время плавания. :)
'13
113
Утверждения - не спасательная шлюпка, это система обнаружения айсберга. Поскольку пользователь не управляет кораблем, утверждение в коде релиза просто говорит им, что они обречены; это не позволяет им избежать айсберга.
Стефан
97

Из полного кода

8 Защитное программирование

8.2 Утверждения

Утверждение - это код, который используется во время разработки - обычно подпрограмма или макрос - который позволяет программе проверять себя во время работы. Когда утверждение верно, это означает, что все работает, как ожидалось. Если значение равно false, это означает, что в коде обнаружена непредвиденная ошибка. Например, если система предполагает, что файл информации о клиенте никогда не будет содержать более 50 000 записей, программа может содержать утверждение о том, что количество записей меньше или равно 50 000. Пока количество записей меньше или равно 50 000, утверждение будет молчать. Однако, если он встречает более 50 000 записей, он громко «утверждает», что в программе есть ошибка.

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

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

(...)

Обычно вы не хотите, чтобы пользователи видели сообщения с утверждениями в рабочем коде; Утверждения в первую очередь предназначены для использования при разработке и обслуживании. Утверждения обычно компилируются в код во время разработки и компилируются из кода для производства. В ходе разработки утверждения удаляют противоречивые предположения, неожиданные условия, неверные значения, передаваемые в подпрограммы и т. Д. Во время производства они компилируются из кода, чтобы утверждения не снижали производительность системы.

хуан
источник
2
В книге «Написание твердого кода» также подробно обсуждается использование assert. Они отличный инструмент для отладки!
zooropa
39

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

Debug.Assert(someObject != null, "someObject is null! this could totally be a bug!");
thelsdj
источник
Если я добавлю строку кода, аналогичную вашей, приведенной выше, при запуске моей программы выдается следующая ошибка: «ошибка CS0103: имя« Debug »не существует в текущем контексте». Нужно ли какое-то использование оператора, чтобы заставить его работать?
Джош Десмонд
4
@JoshDesmondSystem.Diagnostics
Синджай,
16

Assert также дает вам еще одну возможность посмеяться над навыками дизайна пользовательского интерфейса Microsoft. Я имею в виду: диалог с тремя кнопками Abort, Retry, Ignore и объяснение того, как их интерпретировать в строке заголовка!

Джо
источник
3
Прервать / Повторить / Игнорировать - это классика! Было ли это утверждение, которое заставляло Windows 3.1 отображать это постоянно?
Devlord
В основном это потому, что он использует MessageBox, который, как вы говорите, восходит к Windows 3.1, и имеет только предопределенные ярлыки кнопок. Таким образом, вы можете понять, почему взломан, но не почему он все еще существует в 2008 году!
Джо
4
@Joe Это то, что должны видеть только разработчики, а не конечные пользователи, поэтому обновление, вероятно, является крайне низким приоритетом. Если это мешает, вы можете изменить коллекции Debug.Listeners или Trace.Listeners, чтобы заменить обработчик по умолчанию на тот, который делает все, что вы хотите.
Дэн возится с огнем
5
И теперь наступил 2019 год, и все те же диалоговые окна и кнопки все еще здесь!
Бук
10

Assert позволяет вам утверждать условие (post или pre), применяемое в вашем коде. Это способ документировать ваши намерения и заставить отладчик сообщать вам диалог, если ваше намерение не выполнено.

В отличие от точки останова, Assert идет вместе с вашим кодом и может использоваться для добавления дополнительной информации о вашем намерении.

Джефф Йейтс
источник
10

Assert может помочь вам разделить поведение обмена сообщениями между тестированием и выпуском. Например,

Debug.Assert(x > 2)

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

Райан
источник
10

Прежде всего , Assert()метод доступен для Traceи Debugклассов.
Debug.Assert()выполняется только в режиме отладки.
Trace.Assert()выполняется в режиме отладки и выпуска.

Вот пример:

        int i = 1 + 3;
        // Debug.Assert method in Debug mode fails, since i == 4
        Debug.Assert(i == 3);
        Debug.WriteLine(i == 3, "i is equal to 3");

        // Trace.Assert method in Release mode is not failing.
        Trace.Assert(i == 4);
        Trace.WriteLine(i == 4, "i is equla to 4");

        Console.WriteLine("Press a key to continue...");
        Console.ReadLine();

Запустите этот код в режиме отладки, а затем в режиме выпуска.

введите описание изображения здесь

Вы заметите, что в режиме отладки ваш Debug.Assertоператор кода не работает, вы получаете сообщение, показывающее текущую трассировку стека приложения. Этого не происходит в режиме Release, поскольку Trace.Assert()условие истинно (i == 4).

WriteLine() Метод просто дает вам возможность записать информацию в вывод Visual Studio. введите описание изображения здесь

Серж волошенко
источник
5

Утверждения имеют большое значение в Проектировании по контракту (DbC), который, как я понимаю, был представлен / одобрен Мейером, Бертандом. 1997. Создание объектно-ориентированного программного обеспечения.

Важной особенностью является то, что они не должны вызывать побочных эффектов, например, вы можете обработать исключение или предпринять другой шаг с оператором if (защитное программирование).

Утверждения используются для проверки предварительных / последующих условий контракта, отношений клиент / поставщик - клиент должен убедиться, что предварительные условия поставщика выполнены, например. отправляет 5 фунтов стерлингов, и поставщик должен убедиться, что условия выполнены, например. доставляет 12 роз. (Просто простое объяснение клиента / поставщика - можете принять меньше и поставить больше, но об утверждениях). C # также вводит Trace.Assert (), который может использоваться для выпуска кода.

Чтобы ответить на вопрос, да, они все еще полезны, но могут добавить сложность + читабельность к коду и время + трудно поддерживать. Должны ли мы по-прежнему использовать их? Да, мы все будем их использовать? Скорее всего, нет или не так, как описывает Мейер.

(Даже курс OU Java, на котором я изучал эту технику, показал только простые примеры, а остальная часть кода не применяла правила утверждения DbC для большей части кода, но предполагалось, что она используется для обеспечения правильности программы!)

Knightlore
источник
3

Я думаю об этом как Debug.Assert - это способ заключить договор о том, как должен вызываться метод, сосредоточив внимание на особенностях значений параметра (а не только типа). Например, если вы не должны посылать нулевое значение во втором параметре, вы добавляете Assert вокруг этого параметра, чтобы сказать потребителю не делать этого.

Это мешает кому-то использовать ваш код тупым способом. Но это также позволяет этому головокружительному способу перейти к производству и не давать неприятного сообщения клиенту (при условии, что вы собираете сборку Release).

Флори
источник
6
Важно отметить, что недопустимые параметры в открытых методах должны вызывать исключения аргументов. Только частные методы должны проверять ввод с утверждениями. Ценности, которые приходят извне, всегда подозрительны!
Джеффри Л Уитледж