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"); 

因此消息和条件是相同的。 然而,这会让人们在看到exception报告时感到困惑,然后想一想,“如果引用有效,那么为什么会抛出exception?”。

最后,我想,为什么不做一个中立的陈述,这说明必须是真的:

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

以上哪项是最佳做法? 我想得到正确的消息,因为我计划在整个地方使用断言,以防止数据的不规则,为此我启用运行时检查。

值得一提的是,虽然没有针对失败代码合同的用户消息指南,但是有一个名为Expectation Describing Message的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用户。

代码约定(断言,前置和后置条件以及不变量)用于检测代码未设计用于处理的带外操作条件。 它们不应被用作validation的第一点,因此, Contracts不应与上下文用户消息有关。 演示/服务层中的上游validation应该已经识别出任何无效的用户或服务客户端输入。

鉴于该消息仅在合同失败时显示,理论上在生产代码中永远不会出现,这意味着此处的目标“用户”受众将是或其他开发人员,因此应该定制消息以帮助您快速调试它(如果你需要一条消息 – 堆栈跟踪和行号通常就足够了,IMO)。 我想参数名称userMessage可能是一个不幸的选择。