Код C# Контракты Параметр userMessage

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

У меня есть следующее утверждение в моем коде:

Contract.Assert(IsValidReferenceData(refData));

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

Сначала я думал

Contract.Assert(IsValidReferenceData(refData), "Payment Reference is not valid");

Но потом я подумал, что userMessage полностью противоположно логическому условию, поэтому я переписал его так:

Contract.Assert(IsValidReferenceData(refData), "Payment Reference is valid");

Поэтому сообщение и условие одинаковы. Однако это может сбить людей с толку, когда они увидят отчет об исключении, а затем подумают: "Подождите, если ссылка действительна, тогда почему было выдано исключение?".

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

Contract.Assert(IsValidReferenceData(refData), "Payment Reference must be valid");

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

3 ответа

Решение

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

Итак, имея код.Net, я решил посмотреть, что они используют в качестве параметра, вот результат:

"hashcode >= 0"
"Race condition detected in usages of Hashtable - multiple threads appear to be writing to a Hashtable instance simultaneously!  Don't do that - use Hashtable.Synchronized."
"Invalid MaxPrimeArrayLength"
"Missing case in GetRandomizedEqualityComparer!"
"We increment our current index by 8, so our buffer size must be a multiple of 8"
"key shouldn't be null!"
"Size is not zero"
"Didn't set Console::_out or _error appropriately!"
"Setting the foreground color before we've read the default foreground color!"

Гораздо больше здесь: http://pastebin.com/zPgU1ALe

В основном ответ таков: пишите все, что вы хотите, это сообщение предназначено для быстрой отладки, а не для ваших пользователей API.

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

Учитывая, что сообщение будет отображаться только в случае сбоя контракта, что в теории никогда не должно происходить в производимом коде, это означает, что целевой "пользовательской" аудиторией здесь будет ВЫ или коллега-разработчик, поэтому сообщение следует адаптировать, чтобы помочь вам в быстрая его отладка (если вам вообще нужно сообщение - трассировки стека и номера строки обычно достаточно, IMO). Имя параметра userMessage наверное неудачный выбор, наверное.

Другие вопросы по тегам