我最近安装了代码合同工具(.NET 的代码合同)和代码合同编辑器扩展 VS2012,但在让静态检查器正常工作时遇到了一些麻烦。
当我在以下代码上运行 Code Contracts 的静态检查器时(第二个假设被注释掉)
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.Contracts;
public class TestClass
{
public ReadOnlyCollection<byte> Foo()
{
Contract.Ensures(Contract.Result<ReadOnlyCollection<byte>>().Count == 4);
IList<byte> list = new byte[4];
Contract.Assume(list.Count == 4);
var returnValue = new ReadOnlyCollection<byte>(list);
//Contract.Assume(returnValue.Count == 4);
return returnValue;
}
}
我收到“确保未经证实”的警告读数:
CodeContracts:确保未经证实:
Contract.Result<ReadOnlyCollection<byte>>().Count == 4
它声称该Foo
方法的保证未经证实。但是,当我将鼠标悬停在 的构造函数上时ReadOnlyCollection<T>
,我可以看出Count
构造对象的属性确保等于参数的Count
属性list
:
也就是说,静态检查器应该能够判断returnValue.Count == 4
(即 的确保Foo
)成立。如果我取消注释第二个假设,警告确实会消失,但假设我的方法的确保非常有效,这会大大违背静态检查器的目的。
我认为问题可能是只有编辑器扩展知道包含构造函数(mscorlib.Contracts.dll)的确保的合同引用程序集,所以它列出了静态检查器不知道的合同。
我尝试修改项目范围的 Extra Contract Library Paths 设置无济于事,我认为这不是解决问题的正确方法。
我的推理是正确的,即静态检查器没有使用合同参考程序集正确配置,还是我遗漏了其他东西?如果我是对的,我将如何修复配置?
我在用着
- Visual Studio 终极版 2012 更新 3
- 代码合同工具版本 1.5.60502.11
- Code Contracts Editor Extensions VS2012 版本 1.5.64024.12
编辑:静态检查器似乎确实找到了合同引用程序集,并且它可以像我最初预期的那样与其他类甚至ReadOnlyCollection<T>
该类的方法一起工作。例如,以下方法的静态分析工作得很好。
public int Boo()
{
Contract.Ensures(-1 <= Contract.Result<int>());
Contract.Ensures(Contract.Result<int>() < 4);
IList<byte> list = new byte[4];
var collection = new ReadOnlyCollection<byte>(list);
Contract.Assume(collection.Count == 4);
return collection.IndexOf(0);
}
需要对属性进行假设,Count
因为构造函数的确保仍然不起作用。IndexOf
另一方面,该方法的保证效果很好。
现在我想知道的是为什么静态检查器不能识别ReadOnlyCollection<T>
构造函数的确保。这可能是静态分析器中的错误吗?