C# 代码契约静态检查无法正常工作?
我在构造函数中创建了一个具有代码约定的类,CodeTypes具有字符串属性列表C# 代码契约静态检查无法正常工作?,c#,.net,code-contracts,C#,.net,Code Contracts,我在构造函数中创建了一个具有代码约定的类,CodeTypes具有字符串属性列表 Contract.Requires(type == CodeTypes.AdmitDx1 || type == CodeTypes.AdmitDx2 || type == CodeTypes.AdmitDx3 || type == CodeTypes.DX || type == CodeTypes.CPT || type == CodeTypes.HCPCS || type == CodeTypes.PX); 在
Contract.Requires(type == CodeTypes.AdmitDx1 || type == CodeTypes.AdmitDx2
|| type == CodeTypes.AdmitDx3 || type == CodeTypes.DX
|| type == CodeTypes.CPT || type == CodeTypes.HCPCS
|| type == CodeTypes.PX);
在那之后,警告出现在我使用这个类的地方,因为不同的值被放入。到目前为止还不错
然后我转到一段有投诉的代码,添加了if语句的对立面,并抛出了一个异常
警告仍然存在
然后,我在if语句的对面添加了一个return语句
警告仍然存在
然后我放了一个大的if/else,在那里,只有在合同中的条件是有意义的情况下才调用该类
警告仍然存在
然后,我用带有该条件的if语句包围了合同
警告消失了
这是怎么回事?我希望前3个选项能起作用,我真的很想使用选项1。最好的办法是什么
编辑调用代码—合同存在于CreateCodeFromType的构造函数中:
//Type is an XElement that is passed into the method as a parameter
if (type == null || (type.Value != CodeTypes.AdmitDx1 && type.Value != CodeTypes.AdmitDx2
&& type.Value != CodeTypes.AdmitDx3 && type.Value != CodeTypes.DX
&& type.Value != CodeTypes.CPT && type.Value != CodeTypes.HCPCS
&& type.Value != CodeTypes.PX))
{
throw new ValidationException("Type is invalid.");
}
else
{
var newCode = (new CreateCodeFromType(type.Value).CreateCode(term.Value));
}
静态检查器并不完美。它仍在开发中,即使它完成了,也不可能知道一切 现在,您可以使用
Contract.假设并传递条件,给静态检查器一个提示
此外,请随时更新CC版本。他们目前的版本是1.4.31130.0,并计划很快发布另一个版本。在开发的这一点上,静态检查器看到了每个版本的增量改进。如果您提到的“另一段代码”在另一个方法中,而不是在构造函数中,那么您必须将参数保存到构造类型的字段中。在这种情况下,当条件不满足时,静态检查器无法基于抛出或返回检查任何内容,因为在条件满足后,另一个线程可能会更改字段,从而使条件失败。要防止出现这种情况下的警告,请使用压缩变量方法属性
如果这段代码仍然在构造函数中,我想不出静态检查器不能忽略警告的任何原因(但是,如果您已经有了契约。Requires
前提条件,为什么还要使用If语句?)。在这种情况下,我会责怪静态检查器的缺陷,就像斯蒂芬一样
编辑:举个例子,我能看出问题所在
我说过静态检查器不能保证任何字段,因为其他线程可能会弄乱这些字段。type.Value是一个字段,因此静态检查器会警告您可能违反合同,这是合乎逻辑的。我甚至希望在你声称警告消失的情况下得到警告(或者我误解了你)。要解决这个问题,创建一个局部变量,然后您就得到了一个静态检查器可以推理的东西。
因此,请尝试以下方法:
if (type == null) throw new ArgumentNullException();
var xElementValue = type.Value;
if(xElementValue != CodeTypes.AdmitDx1 && xElementValue != CodeTypes.AdmitDx2
&& xElementValue != CodeTypes.AdmitDx3 && xElementValuee != CodeTypes.DX
&& xElementValue != CodeTypes.CPT && xElementValue != CodeTypes.HCPCS
&& xElementValue != CodeTypes.PX) throw new ValidationException("Type is invalid.");
//And now you should be able to give xElementValue as argument without receiving warnings.
或者,如果您想使用合同,请使用
Contract.Requires(type != null);
var xElementValue = type.Value;
Contract.Requires(xElementValue == CodeTypes.AdmitDx1 || xElementValue== CodeTypes.AdmitDx2
|| xElementValue== CodeTypes.AdmitDx3 || xElementValue== CodeTypes.DX
|| xElementValue== CodeTypes.CPT || xElementValue== CodeTypes.HCPCS
|| xElementValue == CodeTypes.PX);
我希望这两种解决方案的警告不会显示它们自己。我如何判断我使用的是哪个版本?它位于“项目属性”下的“代码合同”选项卡上。我看到版本号是代码合同下载的一部分。上一次更新是在12月,我已经用确切的条件更新了样本。参数类型是string,但它是从我认为是对象的XElement.Value赋值的。我可以将XElement.Value强制转换为字符串,还是必须在调用方法中将其作为字符串?我有if语句和异常,因为代码契约在发布时在运行时被关闭。这不是一种有效的做事方式吗?这对我们这里来说是很新的。