Search code examples
c#.netcode-contracts

How to prevent Code Contracts from automatically creating precondition checks?


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


Solution

  • 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:

    public virtual void WriteRaw(string data)
    {
        Contract.Requires(!string.IsNullOrEmpty(data), null, "!string.IsNullOrEmpty(data)");
    }
    

    As far as I know, you can't disable it without disabling contract checking.