Code Contracts: How they look after compiling?

When you are using new tools that make also something at code level then it is good idea to check out what additions are made to code during compilation. Code contracts have simple syntax when we are writing code at Visual Studio but what happens after compilation? Are our methods same as they look in code or are they different after compilation? In this posting I will show you how code contracts look after compiling.

In my previous examples about code contracts I used randomizer class with method called GetRandomFromRangeContracted.

public int GetRandomFromRangeContracted(int min, int max)
{
   
Contract.Requires<ArgumentOutOfRangeException
>(
        min < max,
       
"Min must be less than max"
    );
 
   
Contract
.Ensures(
       
Contract.Result<int
>() >= min &&
       
Contract.Result<int
>() <= max,
       
"Return value is out of range"
    );
 
   
return _generator.Next(min, max);
}

Okay, it is nice to dream about similar code when we open our assembly with Reflector and disassemble it. But… this time we have something interesting. While reading this code don’t feel uncomfortable about the names of variables. This is disassembled code. .NET Framework internally allows these names. It is our compilators that doesn’t accept them when we are building our code.

public int GetRandomFromRangeContracted(int min, int max)
{
   
int
Contract.Old(min);
   
int
Contract.Old(max);
   
if
(__ContractsRuntime.insideContractEvaluation <= 4)
    {
       
try
        {
            __ContractsRuntime.insideContractEvaluation++;
            __ContractsRuntime.Requires<
ArgumentOutOfRangeException
>(
               min < max,
              
"Min must be less than max", "min < max"
);
        }
       
finally
        {
            __ContractsRuntime.insideContractEvaluation--;
        }
    }
   
try
    {
        Contract.Old(min) = min;
    }
   
catch (Exception
exception1)
    {
       
if (exception1 == null
)
        {
           
throw
;
        }
    }
   
try
    {
        Contract.Old(max) = max;
  
   
catch (Exception
exception2)
    {
       
if (exception2 == null
)
        {
           
throw
;
        }
    }
   
int CS$1$0000 = this
._generator.Next(min, max);
   
int Contract.Result<int
>() = CS$1$0000;
   
if
(__ContractsRuntime.insideContractEvaluation <= 4)
    {
       
try
        {
            __ContractsRuntime.insideContractEvaluation++;
            __ContractsRuntime.Ensures(
               (Contract.Result<
int
>() >= Contract.Old(min)) &&
               (Contract.Result<
int
>() <= Contract.Old(max)),
              
"Return value is out of range"
,
              
"Contract.Result<int>() >= min && Contract.Result<int>() <= max"
);
        }
       
finally
        {
            __ContractsRuntime.insideContractEvaluation--;
        }
    }
   
return Contract.Result<int>();
}

As we can see then contracts are not simply if-then-else checks and exceptions throwing. We can see that there is counter that is incremented before checks and decremented after these whatever the result of check was.

One thing that is annoying for me are null checks for exception1 and exception2. Is there really some situation possible when null is thrown instead of some instance that is Exception or that inherits from exception?

Conclusion

Code contracts are more complex mechanism that it seems when we look at it on our code level. Internally there are done more things than we know. I don’t say it is wrong, it is just good to know how our code looks after compiling. Looking at this example it is sure we need also performance tests for contracted code to see how heavy is their impact to system performance when we run code that makes heavy use of code contracts.

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    5 thoughts on “Code Contracts: How they look after compiling?

    • May 24, 2010 at 11:56 am
      Permalink

      You need help from the compiler.

      Think about the above example and inheritance. Contracts should be inherited. That’s why they are more than asserts

    • May 24, 2010 at 1:31 pm
      Permalink

      > This is disassembled code. .NET Framework internally allows these names. It is our compilators that doesn’t accept them when we are building our code.

      It has nothing to do with the framework. It is valid IL and hence the runtime accepts it. Further, you could develop a compiler that produces such names. Or you could use Reflection to emit such IL names.

    • May 24, 2010 at 2:01 pm
      Permalink

      That’s what I’m saying. In IL it is possible to use whatever names you like. If you try something like this in VS IDE on C# or VB.NET then you are not allowed to use variable names like these.

    • May 26, 2010 at 2:01 pm
      Permalink

      Agree that the null checks in the handlers are bothersome. They are a technical device to keep FxCop from issuing spurious warnings.

    • June 22, 2011 at 9:03 am
      Permalink

      Code contracts how they look after compiling.. Dandy :)

    Leave a Reply

    Your email address will not be published. Required fields are marked *