CodeContracts:可能在空引用上调用方法
I'm having an argument with the CodeContracts static analysis tool.
My code:
The tool tells me that instance.bar
may be a null reference. I believe the opposite.
Who is right? How can I prove it wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
更新:问题似乎是静态字段不支持不变量。
第二次更新:下面概述的方法是目前推荐的解决方案。
一种可能的解决方法是为
实例
创建一个属性,确保
是您想要保留的不变量。 (当然,您需要假设
它们才能证明Ensure
。)完成此操作后,您就可以使用该属性,并且所有不变量都应该被证明正确。这是使用此方法的示例:
Update: It seems the problem is that invariants are not supported for static fields.
2nd Update: The method outlined below is currently the recommended solution.
A possible workaround is to create a property for
instance
thatEnsure
s the invariants that you want to hold. (Of course, you need toAssume
them for theEnsure
to be proven.) Once you have done this, you can just use the property and all the invariants should be proven correctly.Here's your example using this method:
代码合同是对的。在调用
BarLength()
方法之前,没有什么可以阻止您设置instance.bar = null
。CodeContracts is right. There is nothing stopping you from setting
instance.bar = null
prior to calling theBarLength()
method.您的代码包含一个私有静态初始化实例:
您是否假设这意味着实例构造函数将始终在访问任何静态方法之前运行,从而确保
bar
已初始化?在单线程的情况下,我认为你是对的。
事件顺序为:
Foo.BarLength()
Foo
的静态初始化(如果尚未完成)instance< 的静态初始化/code> 与
Foo
实例Foo.BarLength()
但是,每个应用程序域仅触发类的静态初始化一次 - 并且 IIRC 不会阻塞确保在调用任何其他静态方法之前它已完成。
因此,您可能会遇到以下情况:
Foo.BarLength()
Foo
的静态初始化(如果尚未完成)开始Foo.BarLength()
Foo
的静态初始化,因为那是已经进行Foo.BarLength()
null
静态成员instance
合约分析器无法知道您永远不会以多线程方式运行代码,因此必须谨慎行事。
Your code includes a private static initialized instance:
Are you assuming that this means the instance constructor will always have run before access to any static method, therefore ensuring
bar
has been initialized?In the single threaded case, I think you're right.
The sequence of events would be:
Foo.BarLength()
Foo
(if not already completed)instance
with instance ofFoo
Foo.BarLength()
However, static initialization of a class is only ever triggered once per App Domain - and IIRC there's no blocking to ensure it's completed before any other static methods are called.
So, you could have this scenario:
Foo.BarLength()
Foo
(if not already completed) startsFoo.BarLength()
Foo
because that's already underwayFoo.BarLength()
null
static memberinstance
There's no way the Contracts analyser can know that you'd never run the code in a multithreaded way, so it has to err on the side of caution.
如果将字段“bar”标记为只读,则应该满足静态分析器的要求,即在构造函数执行后该字段永远不会被设置为其他任何内容。
If you mark the field 'bar' as readonly, that should satisfy the static analyzer that the field will never be set to anything else after the ctor executes.
我同意你的看法。
instance
和bar
都是私有的,因此 CodeContracts 应该能够知道instance.bar
永远不会设置为 null。I agree with you.
instance
andbar
are both private, so CodeContracts should be able to knowinstance.bar
is never set to null.