我签了一份合同:
for (int i = 0; i < delegateParameterTypes.Length; i++)
{
Contract.Assert(i < delegateParameterTypes.Length);
Contract.Assert(delegateParameterTypes.Length == methodParameters.Length + (1));
// Q.E.D.
Contract.Assert(i < methodParameters.Length + (1));
}
前两次传球分析很好但是第三次说断言是未经证实的,一个接一个?考虑后卫。 这似乎是简单的数学。有什么我想念的吗?
尝试使用字符串数组和本地值似乎工作正常。可能会以某种方式与.Length电话有关吗?我尝试将int交换到UInt16以查看它是否是由于循环中的缓冲区溢出,但那也不是。
答案 0 :(得分:0)
嗯,我唯一能想到的是静态分析器对这些断言有问题。关注我:
Contract.Assert(i < delegateParameterTypes.Length);
。假设这是真的,我们继续。delegateParameterTypes.Length
的呼叫和上面的步骤1之间是否有任何关于Contract.Assert(predicate)
的变化。你和我都知道没有发生任何事情,但是分析器没有 - 尽管事实上两行代码是相邻的(谁说没有某些线程在那里触及共享状态?)Contract.Assert(delegateParameterTypes.Length == methodParameters.Length + (1));
分析师会对此进行检查,这也没关系。delegateParameterTypes
或methodParameters
- QED的任何内容发生了变化,在下一行中对Contract.Assert(i < methodParameters.Length + (1));
进行了未经证实的断言。同样,可能存在与这些事物相关联的一些共享全局状态,并且该状态可能在对Contract.Assert
的两次调用之间发生了变化。请记住,对于您和我来说,代码看起来是线性和同步的。现实是或可能完全不同,静态分析器不能在连续调用Contract.Assert
之间对这些对象的状态做出假设。
但是可能有用:
int delegateParameterTypesLength = delegateParameterTypes.Length;
int methodParametersLength = methodParameters.Length + 1;
for (int i = 0; i < delegateParameterTypesLength; i++)
{
Contract.Assert(delegateParameterTypesLength == methodParametersLength);
// QED
Contract.Assert(i < methodParametersLength);
}
通过将长度分配给变量,静态分析器现在可以知道这些值不会在for
循环内发生变化,也不会在分配它们的方法外部发生变化。现在,您要将i
与已知不会更改的值进行比较。现在,静态分析器可以对这些值的比较做出一些推论,并且应该能够证明这些断言。