Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#4.0

New .NET Feature - Code Contracts

3.44/5 (9 votes)
12 Aug 2009CPOL4 min read 33.4K   61  
Code Contracts provide a language-agnostic way to express coding assumptions in .NET programs

Introduction

.NET 4.0 is just around the corner and many new features are making their presence felt. One such feature is related to the quality of .NET code. This functionality just looks like a cool wrapper for Debug.Assert. But exploring details helped me understanding its power. [And hence, I guess, I am writing this article.]

If you prefer to watch this demo on video – then check out this channel 9 clip. Code contract bits can be downloaded from here and it works with VS 2008 standard and TS edition.

Ok – so after you install the bits – fireup VS 2008 and create a new console application. Add a reference to the Microsoft.Contracts library as shown below and insert:

C#
using System.Diagnostics.Contracts 

and

C#
using System.Diagnostics 

at the top of your program.

ref.JPG

Just so we understand it clearly – let's write a class SimpleCalculate and use our old friend Debug.Assert to code defensively.

C#
class SimpleCalculate
{
    private int num1;
    private int num2;

    public SimpleCalculate(int numberone, int numbertwo)
    {
        num1 = numberone;
        num2 = numbertwo;
    }

    public int Divide()
    {
        Debug.Assert(num2 > 0, "numbertwo should be greater than 0");
        if (num2 > 0)
            return num1 / num2;

        return num1;
    }
}

And our console app will look like:

C#
class Program
    {
        static void Main()
        {
            SimpleCalculate sc = new SimpleCalculate(4, 0);
            Console.WriteLine("Result is {0}", sc.Divide());
            Console.ReadLine(); 
        }
    }

If we run this code – big surprise – Debug.Assert will fire [if you build the project in debug mode] and will populate the following window:

debugassert.JPG

Fine – this is a good enough solution. So why do we need anything else. Let’s rewrite the same class with code contracts.

C#
class ClaculateWithContracts
    {
        private int num1;
        private int num2;

        public ClaculateWithContracts(int numberone, int numbertwo)
        {
            num1 = numberone;
            num2 = numbertwo; 
        }

        public int Divide()
        {
            Contract.Requires(num2 > 0); 
            if (num2 > 0)
                return num1 / num2;

            return num1;
        }
    }

So if you run this code as:

C#
ClaculateWithContracts cc = new ClaculateWithContracts(4, 0); 

Console.WriteLine("Result is {0}", cc.Divide()); 

Nothing will happen. In fact, because of the high quality of my code – output will be 4. [i.e. this code will not break – that’s why I am an architect – I can write unbreakable code. Figure out why the output is 4.]

The reason our contract is not working is because we need an additional step to use this contract. Right click on the project and go to the properties as shown below:

properties.JPG

And from properties window, select Code Contract and check the perform runtime contract checking checkbox as shown below:

addcontract.JPG

Now if you run the code again, our contract will hit. It will produce the following output:

contractassertion.JPG

Not much different than what Debug.Assert did – correct? But wait a minute before you close the browser window... let me finish the story here. One important thing to notice is the timing when the assertion window is produced. Debug.Assert will hit when you reach up to that condition, whereas  pre condition failed window is populated as soon as ClaculateWithContracts cc = new ClaculateWithContracts(4, 0); line is executed. You can check the call stack to confirm this claim.

Now the thing that sucks the most is that contract static checking is only available in VSTS, and I am using VS 2008 pro SP1. So I can't talk about that feature here. But it is a great way to harden your code.

Now a little bit of decoupling – comment out the line Contract.Requires(num2 > 0); and add a special method – just type cim and VS code snippet will show up – hit the tab twice to insert the boiler plate code.

C#
[ContractInvariantMethod]
 protected void ObjectInvariant()
 {
   Contract.Invariant(this.num2>0);
 }

Now if you run the program, you will get the following output:

conditionassertion.JPG

So by doing this, we opened up a communication channel for ClaculateWithContracts to express what is acceptable and what is not acceptable for it to work with. Again, if you trace the call stack – this window will pop up at the time of the instantiation of ClaculateWithContracts.

Ok – you are still not convinced that this is any better than Debug.Assert. So let's add one more thing – a money back guarantee that our method will always behave and will do the right thing and nothing else – all the time. WOW – what a baloney! Am I smoking something – I mean if the code will work right 100% of the time, then where is the job security? [if (U.MyBoss) please ignore; else continue;]

Anyways, we can add a guarantee that our method will always return a non-zero result. Let's modify our method to implement this functionality. 

C#
public int Divide()
      {
          Contract.Ensures(Contract.Result<int />() > 0);
          if (num2 > 0)
              return num1 / num2;

          return num1;
      }

Notice the Contract.Ensures, it means the result coming out of this method will always be greater than 0. Just press ce to insert Contract.Ensures snippet and inside it type crr to insert the contract result snippet. So now we have two way traffic – ClaculateWithContracts is very clear about what is acceptable and what its public methods will do. So if you call this type as:

C#
ClaculateWithContracts cc = new ClaculateWithContracts(4, 8); 

you will get a message like the one shown below explaining the postcondition failure:

postconditionassertion.JPG

Now for those who are paying close attention to this implementation – we have Contract.Ensures(Contract.Result<int>() > 0); before the return statement and in fact the actual logic. So how does this contract work? I mean, if the logic is still not executed then how come this code is evaluating the end result? Magic – not at all.

You have reached upto this point only proves your determination to learn new technology. So please go ahead and figure out this last missing link. Let me know the answer on 1800 call abhi!

Happy programming!

History

  • 12th August, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)