我正在使用代码合同来验证输入字符串。输入合同,用简单的英语:
转换为代码,我最终得到一个看起来像这样的构造函数...
private readonly string ruleName;
protected Lexer(string ruleName)
{
Contract.Requires(!string.IsNullOrEmpty(ruleName));
Contract.Requires(char.IsLetter(ruleName, index: 0));
Contract.Requires(Contract.ForAll(ruleName.ToCharArray(), c => char.IsLetterOrDigit(c) || c == '-'));
this.ruleName = ruleName;
}
对应的班级不变......
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(!string.IsNullOrEmpty(this.ruleName));
Contract.Invariant(char.IsLetter(this.ruleName, index: 0));
Contract.Invariant(Contract.ForAll(this.ruleName.ToCharArray(), c => char.IsLetterOrDigit(c) || c == '-'));
}
最后一份合同似乎混淆了静态合同检查工具。静态检查器声称它无法证明谓词对于ruleName.ToCharArray()
的返回值中的每个字符都是真的。
这让我感到不安,因为ToCharArray()
是确定性的。字符串是不可变的,因此在字符串上调用ToCharArray()
将始终返回相同的值,因此谓词将始终保持。
有没有办法以静态合同检查器可以证明的方式表达我的字符串验证?