如何防止代码契约自动创建前提条件检查?
我遇到了 Microsoft 代码合同的奇怪行为,我不理解也不知道如何解决。
我在项目中使用代码契约,通常是为了检查先决条件(参数值),并且通常没有任何问题。然而,在这一类中,代码契约模块似乎会自动对所有采用参数的方法插入前置条件检查。
例如,这是我的原始代码:
public override void WriteRaw(string data)
{
this.writer.WriteRaw(data);
}
这是我使用 Reflector 反编译程序集时看到的内容:
public override void WriteRaw(string data)
{
__ContractsRuntime.Requires(string.IsNullOrEmpty(data) == 0, null, "!string.IsNullOrEmpty(data)");
this.writer.WriteRaw(data);
Label_0028:
return;
}
即使在对我的代码进行了详尽的研究和分析之后,我能得出的最佳诊断是它只发生在继承的类上/实现抽象的System.Xml.XmlWriter
。在所有其他情况下,只有当我手动添加合同时,合同才会存在。
在 99% 的情况下,我欢迎通过代码契约进行自动参数检查(前提是我可以控制它)。但所讨论的代码是一个包装 XML 编写器,XslCompilerTransform 使用它来省略正确的 XHTML。如果 XSL 样式表包含类似
的内容,而 xyz
不包含不存在,因为自动生成的合同导致转换以不必要的异常结束,除非我完全关闭合同,否则我无法绕过该异常。
有谁有这方面的经验并能指出我正确的方向吗?
谢谢, 伊戈尔
I have come across a strange behavior with Microsoft Code Contracts that I don't understand and don't know how to solve.
I am using Code Contracts in my projects, typically to check the preconditions (argument values), and have generally had no problems with it. However, in this one class, the Code Contracts module seems to automatically insert precondition checks on all methods that take arguments.
For example, this is my original code:
public override void WriteRaw(string data)
{
this.writer.WriteRaw(data);
}
This is what I see when I decompile my assembly with Reflector:
public override void WriteRaw(string data)
{
__ContractsRuntime.Requires(string.IsNullOrEmpty(data) == 0, null, "!string.IsNullOrEmpty(data)");
this.writer.WriteRaw(data);
Label_0028:
return;
}
Even after exhaustive research and analysis of my code, the best diagnosis I could come up with is that it happens only on the class that inherits/implements the abstract System.Xml.XmlWriter
. In all other cases, the contracts will be there only if I add them manually.
In 99% of the cases I would welcome automatic argument checking by code contracts (provided that I can control it). But the code in question is a wrapping XML writer that is used by the XslCompilerTransform to omit proper XHTML. And if the XSL stylesheet contains something like <xsl:value-of select="xyz" disable-output-escaping="yes"/>
where xyz
doesn't exist, because of the contract that was automatically generated the transform ends in an unnecessary exception that I cannot bypass unless I switch off contracts altogether.
Does anyone have some experience with this and can point me in the right direction?
Thanks,
Igor
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这些协定应用于抽象
XmlWriter
接口。您可以通过查看 Reflector 中代码合同安装目录(在我的计算机上位于 C:\Program Files (x86)\Microsoft\Contracts\Contracts.NETFramework\v4.0 中)中的合同引用程序集来看到这一点。当您重写应用了契约的虚拟/抽象方法或接口方法时,它们会自动融入您的代码中。
WriteRaw 的契约是:
据我所知,如果不禁用契约检查,就无法禁用它。
The contracts are applied to the abstract
XmlWriter
interface. You can see this by looking at the contract reference assembly in the code contracts installation directory (on my machine it's in C:\Program Files (x86)\Microsoft\Contracts\Contracts.NETFramework\v4.0) in Reflector.When you override a virtual/abstract method or interface method that has contracts applied, they are automatically woven into your code.
The contract for WriteRaw is:
As far as I know, you can't disable it without disabling contract checking.