代码合同警告“确保未经证实”涉及锁定时
我正在尝试使用以下示例来了解.NET代码合同如何与lock
关键字进行交互:
public class TestClass
{
private object o1 = new object();
private object o2 = new object();
private void Test()
{
Contract.Requires(this.o1 != null);
Contract.Requires(this.o2 != null);
Contract.Ensures(this.o1 != null);
lock (this.o2) {
this.o1 = new object();
}
}
}
当我运行Code Contract静态分析工具时,它会打印Ensures unproven: this.o1 != null
警告: Ensures unproven: this.o1 != null
如果我做任何:
lock
的o2
更改为o1
, lock
块内的o1
更改为o2
, lock
块内添加第二行,将new
object
分配给o2
lock (this.o2)
更改为if (this.o2 != null)
, lock
语句。 警告消失。
但是,将lock
块内的行更改为var temp = new object();
(因此从方法中删除对o1
所有引用)仍会导致警告:
private void Test()
{
Contract.Requires(this.o1 != null);
Contract.Requires(this.o2 != null);
Contract.Ensures(this.o1 != null);
lock (this.o2) {
var temp = new object();
}
}
所以有两个问题:
lock
内发生)? 以下是静态检查器如何处理锁和不变量:
如果你用表单锁(x.foo){...}来锁定某个东西,那么静态检查器会认为x.foo是x的保护锁。 在锁范围的末尾,它假定其他线程可以访问x并修改它。 因此,静态检查器假定x的所有字段只满足锁范围后的对象不变量,仅此而已。
请注意,这不是考虑所有线程交织,只是在锁定范围结束时交织。
将以下代码添加到您的类中:
[ContractInvariantMethod]
private void ObjectInvariants()
{
Contract.Invariant(o1 != null);
}
我无法告诉你为什么,但在这种情况下,静态验证程序似乎确实考虑了私人字段分配以及缺少将其修改为足以证明该字段不会被修改的证据的方法。 这可能是验证器中的错误? 可能值得在守则合同论坛上报告。
链接地址: http://www.djcxy.com/p/12907.html上一篇: Code Contracts warn of "ensures unproven" when locks are involved