怎么免费的我可以在代码中的一个对象不变的?
-
05-07-2019 - |
题
我试图表现出不变在代码合同,并且我认为我会得到的一个例子的一整串名单。它维持一系列内部,具备空间的增加等等,就像 List<T>
, 上。当它需要增加一个项目,将其插入阵列,等等。我想我有三个固定:
- 该计数必须是合理的:非消极的,并在最大,因为缓冲区的大小
- 一切在未使用的部分缓冲区应null
- 每个项目在使用部分的缓冲区应至少为"大"的项目之前
现在,我已经试图执行,以这种方式:
[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));
那是有点丑陋的,虽然它的工作。(这是更好的比我以前的尝试,请注意。)
是我的期望不合理的?是我不变不合理的?
(还询问,作为一个 问题在代码合同的论坛.我会加入任何相关答案在这里我自己。)
解决方案
从(初步)MSDN页它看起来像的合同。所有的成员可以帮助你,与2范围内的合同。本文件并不是很明确的有关其功能。
//untested
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));
其他提示
(我会接受Henk的答案,但我认为这是值得增加这一点。)
这个问题现在已经回答了上 MSDN论坛, 和结果是第一种形式 是不是 预计工作。不变的真的,真的需要一系列的电话 Contract.Invariant
, ,这是所有。
这使得它更加可行的静态检查,以了解不变的,并强制执行。
这种限制可绕过通过简单地把所有的逻辑成一个不同的部件,例如一个 IsValid
酒店,然后叫:
Contract.Invariant(IsValid);
这无疑会搞砸的静态检查,但在某些情况下,它可能是一个有用的替代在一些情况。
是不是设计师重新发明轮子一点?
什么是错的 好老
bool Invariant() const; // in C++, mimicking Eiffel
?
现在C#我们没有常量,但为什么你不能只是定义 Invariant
功能
private bool Invariant()
{
// All the logic, function returns true if object is valid i.e. function
// simply will never return false, in the absence of a bug
}
// Good old invariant in C#, no special attributes, just a function
然后就是用代码的合同条款的功能吗?
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(Invariant() == true);
}
也许是我写的废话,但即使在这种情况下,它会有一些说教的价值时,每个人都告诉我是错误的。
不隶属于 StackOverflow