问题
I am using Code Contracts in C# but I am a bit curious what I should be typing in for the userMessage
parameter. I will give a short example.
I have the following assertion in my code:
Contract.Assert(IsValidReferenceData(refData));
This message will never be displayed to the user, but it would be nice to have an English message description in the exception for myself and other developers/maintainers of the software.
Initially I thought
Contract.Assert(IsValidReferenceData(refData), "Payment Reference is not valid");
But then I thought that the userMessage
is complete opposite to the boolean condition, so I rewrote it as:
Contract.Assert(IsValidReferenceData(refData), "Payment Reference is valid");
Therefore the message and the condition are the same. However that would confuse people when they see the exception report and then think, "hang on, if the reference is valid, then why was an exception thrown?".
Lastly, I could thought, why not make a neutral statement, which says what must be true:
Contract.Assert(IsValidReferenceData(refData), "Payment Reference must be valid");
Which of the above is the best practice? I want to get to get the messages right because I plan to use assertions all over the place, to prevent irregularities in the data, and for that I am enabling run-time checking.
回答1:
It's worth mentioning that although there are no guidelines for user messages on failing code contracts, there is a xUnit test pattern called Expectation Describing Message that fits your last example. By answering the question to what should have happened in the assertion message, you fulfill both of your goals: code readability + providing a helpful, self-explanatory debug message.
回答2:
So, having .Net code I decided to look what do they use as parameter, this is the result:
"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!"
Much more here: http://pastebin.com/zPgU1ALe
Basically answer is: write whatever you want, this message is intended for you to debug quickly, not so much for your api users.
回答3:
Code Contracts (assertions, pre and post conditions, and invariants) are there to detect out-of-band operating conditions for which your code isn't designed to handle. They shouldn't be used as the first point of validation, and as a result, Contracts
should not be concerned with contextualized user messages. Upstream validation in the presentation / service tiers should have already identified any invalid user or service client input.
Given that the message will only be shown when the contract fails, which in theory should never happen in productionized code, it means the target "user" audience here will be YOU or a fellow developer, so the message should be tailored to assist you in quickly debugging it (if you need a message at all - stack trace and line number generally suffice, IMO). The parameter name userMessage
is possibly an unfortunate choice, I guess.
来源:https://stackoverflow.com/questions/27016808/c-sharp-code-contracts-usermessage-parameter