I’ve heard a little about Code Contracts introduced in .Net 4.0, but until today I hadn’t really looked into it at all. Turns out there is a nice video on youtube by David McCarter here http://www.youtube.com/watch?v=xVhQ9yfo54I
In a nutshell, for the few people who have not come across them yet, they exist in System.Diagnostics.Contracts and they enable you to set preconditions (what does it expect), postconditions (what does it promise) and invariance (what does it maintain).
We know that data is evil. Well, everyone else’s data is evil.
As such, we end up validating parameters to ensure that they are not null, not empty and so forth – an element of hygiene which sometimes gets overlooked.
So if we are so used to putting in these guard conditions though, what do Code Contracts give us? On my cursory look at them, there are some clear benefits.
1. Static checking
You can enable static checking of code contracts so that every time the code is built those contracts will be evaluated. Is there some rarely used code which is carelessly passing in a null reference? rather than it failing at run time in obscure circumstances, my compiler can tell me about it.
2. Checking happens outside the method
When we have guard conditions inside our method, that is the place where checking happens and were errors get reported. We might then have to investigate the stack trace to find out where the actual source of the error is.
Code contracts are located within the method, but preconditions are checked outside the method when anything attempts to call that method. The contracts become part of the method and determines whether it can be called or not. That means that we get an error reported much closer to the actual source of the problem.
The following examples are mostly taken directly from the video
Examples – preconditions
Contract.Requires(ex != null);
This will raise an exception if the parameter ex is null.
Contract.Requires<ArgumentNullException>(ex != null, “My custom error message”);
This will raise an ArgumentNullException if the parameter ex is null, and include a custom error message.
Examples – postconditions
This checks that the string returned by a method is neither null nor whitespace. You can’t use the variable that would be returned from the method, but you can use Contract.Result and give it the type of the return value, which allows this postcondition to be evaluated.
Examples – maintaining state
Contract.EnsuresOnThrow<MyBusinessException>(Contract.OldValue(this.name) == this.name);
Here I want to check that if a MyBusinessException was thrown, a particular value (this.name in this instance) hasn’t changed. Contract.OldValue allows you to reference the original value of a variable for the purposes of this check. If my method didn’t clean up nicely as a result of throwing the exception, then this contract would be violated. Modifying my code to ensure that I handle this situation properly means that this contract can be met.
Something that I want to look into, but haven’t seen any details about yet, is whether there is a performance overhead to using Code Contracts. Underneath the covers it works by rewriting the IDL – there isn’t any magic, ultimately it all has to be code; this is merely a clever and succinct way of enabling it without requiring a lot of complicated coding every time to make it happen.
It looks to me as though this would be a boon in writing code which is more robust, reducing maintenance costs and the probability of live errors. But is it suitable for all environments, or perhaps not for computationally intensive ones? Time and further investigation will tell.
The main source for information is on the Microsoft site here: http://research.microsoft.com/en-us/projects/contracts/
There are additional videos on Microsoft’s Channel9 site here: http://channel9.msdn.com/Search/?Term=code%20contracts