我试图在代码合同中演示不变量,我想我会举一个字符串排序列表的例子。它在内部维护一个数组,有用于添加等的备用空间 - 基本上就像List<T>
. 当它需要添加一个项目时,它将它插入到数组中,等等。我想我有三个不变量:
- 计数必须是合理的:非负数并且最多与缓冲区大小一样大
- 缓冲区未使用部分中的所有内容都应为空
- 缓冲区已用部分中的每个项目都应至少与之前的项目一样“大”
现在,我尝试以这种方式实现它:
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(count >= 0 && count <= buffer.Length);
for (int i = count; i < buffer.Length; i++)
{
Contract.Invariant(buffer[i] == null);
}
for (int i = 1; i < count; i++)
{
Contract.Invariant(string.Compare(buffer[i], buffer[i - 1]) >= 0);
}
}
不幸ccrewrite
的是,正在搞乱循环。
用户文档说该方法应该只是对Contract.Invariant
. 我真的必须像这样重写代码吗?
Contract.Invariant(count >= 0 && count <= buffer.Length);
Contract.Invariant(Contract.ForAll
(count, buffer.Length, i => buffer[i] == null));
Contract.Invariant(Contract.ForAll
(1, count, i => string.Compare(buffer[i], buffer[i - 1]) >= 0));
这有点难看,尽管它确实有效。(这比我之前的尝试要好得多,请注意。)
我的期望不合理吗?我的不变量不合理吗?
(也在代码合同论坛中作为问题提出。我将自己在这里添加任何相关答案。)