代码契约[Type]实现接口方法{Interface.Method},因此无法添加要求
我有以下场景:
public interface ISomething
{
void DoStuff();
//...
}
public class Something : ISomething
{
private readonly ISomethingElse _somethingElse;
//...
public Something (ISomethingElse somethingElse)
{
Contract.Requires(somethingElse != null);
_somethingElse = somethingElse;
}
public void DoStuff()
{
// *1* Please look at explanation / question below
_somethingElse.DoThings();
}
}
在第 1 行并打开静态检查器时,我会收到一条警告,指出 _somethingElse
可能为空,如果我添加合同会给我错误
[Type]实现接口方法{Interface.Method},因此无法添加要求
这里最好做什么?我看到的选项包括
- 一个保护条款,尽管它似乎是 有点极端
Contract.Assume
- 我没有想到的隐藏的第三个选项
请注意,该字段是只读
,因此在构造函数中设置值后,不可能改变。因此,代码合约的警告似乎有点无关紧要。
I have the following scenario:
public interface ISomething
{
void DoStuff();
//...
}
public class Something : ISomething
{
private readonly ISomethingElse _somethingElse;
//...
public Something (ISomethingElse somethingElse)
{
Contract.Requires(somethingElse != null);
_somethingElse = somethingElse;
}
public void DoStuff()
{
// *1* Please look at explanation / question below
_somethingElse.DoThings();
}
}
At line 1 and with the static checker on, I'll get a warning saying that _somethingElse
is possibly null, and if I add a contract it will give me the error
[Type]implements interface method {Interface.Method} thus cannot add requires
What's the best thing to do here? Options I see include
- a guard clause, though it seems a
bit extreme - a
Contract.Assume
- a hidden third option that I haven't thought of
Please note the field is readonly
so after setting the value in the constructor it is not possible to change. Thus, the warning from code contracts seems a bit irrelevant.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
说明
用户手册的第 3 节:合同继承 声明所有前提条件必须在继承/实现链的根方法中定义:
解决方案
在您的情况下,最好的做法是设置一个不变量,声明
_somethingElse
字段永远不为空:这当然总是正确的,因为该字段被标记为
readonly 并在构造函数中初始化。不过,静态检查器无法自行推断这一点,因此您必须通过该不变量显式地告诉它。
您可以选择向构造函数添加后置条件
Contract.Ensures(_somethingElse != null);
,但静态检查器不需要它。Explanation
Section 3: Contract Inheritance of the user manual states that all preconditions must be defined in the root method of an inheritance/implementation chain:
Solution
In your situation, the best course of action is to set up an invariant stating that the
_somethingElse
field is never null:This is of course always true, as the field is marked
readonly
and initialised in the constructor. The static checker isn't able to infer this on its own though, so you must explicitly tell it through that invariant.You can optionally add a postcondition
Contract.Ensures(_somethingElse != null);
to your constructor, but the static checker doesn't require it.