Architecture & DesignUnderstanding and Benefiting from Code Contracts in .NET 4.0

Understanding and Benefiting from Code Contracts in .NET 4.0

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Introduction


Code Contracts is a new feature in the forth-coming .NET 4.0 release. Currently, Code Contracts is being nurtured as an MSDN DevLabs project, which means it has a life on its own outside the official track of the .NET Framework. Being off the beaten path also means that rapid updates are to be expected, just as has happened with the recent web application frameworks like ASP.NET MVC. Code Contracts is planned to become an official part of the framework version 4.0 once it ships.


The main idea of Code Contracts is to let developers have an easier way to define a set of rules for your classes. For example, you might have rules to which the properties and fields of a given class should always conform to. These rules can then be checked both statically at compile-time and at runtime when the application executes. Code Contracts combines a .NET class library with a Visual Studio IDE integration package, and is available from all .NET compatible programming languages such as C# or Visual Basic

The age-old problem of maintaining proper internal state of objects has many incarnations: you could raise exceptions, use assertions, or simply fail methods with an error code if the call in the current context would not be valid. Similar things happen when you set property values: a class could want to make sure a percentage value sits between 0 and 100, or a sales price above the cost, for instance.


Although other possibilities certainly exist, the basic implementation of state management is usually this: first, a method checks the validity of parameters and object’s current state, and then proceeds to do the real work. After this, the method checks to see if all worked correctly, and as the final step, updates the state of itself accordingly. These checks are often called pre and post conditions, respectively.


When you take a look at the implementation of complex and critical classes, the overhead of validating parameters and maintaining state compared to the real work done by the method can be large. It is not uncommon to see that parameters validation and state management take twice as many code lines as the real work done by a method.


This article will talk about Code Contracts and provide a glimpse of how they can be used in real-world applications. The basics of Code Contracts have already been introduced elsewhere on the Internet.com web sites see (Marius Bancila’s article on CodeGuru.com from June, 2009), and this article will only offer a quick recap on the basics, and instead focus in more detail to the workings of Code Contracts.


If you want to try Code Contracts yourself, the easiest way to get started is to download Visual Studio 2010 Beta 1. However, you can also use Code Contracts with Visual Studio 2008 if you first download a separate installer from MSDN DevLabs. You can find links to the download pages at the end of this article. When you install the downloaded package, the installation files will be placed in C:Program FilesMicrosoftContracts.


A quick recap: conditions and invariants


To get you up to speed with Code Contracts quickly, the following example shows how Code Contracts can be used from a C# application. Remember that Code Contracts is a technology under construction, and thus changes to the syntax might become necessary as the product evolves. Nonetheless, this is how you could define a Code Contract today:


  using System.Diagnostics.Contracts;

public class ContractTest
{
private int percentage;

public int Percentage
{
get …
set
{
Contract.Requires((value >= 0) && (value <= 100));
percentage = value;
}
}
}



In the above code listing, the static Requires method of the Contract class (part of the System.Diagnostics.Contracts namespace) is used to define a pre-condition that specifies that when the Percentage property is set, the value must be between 0 and 100 inclusive. In this form, Code Contracts do not differ much from regular assert statements or throwing for instance ArgumentOutOfRangeException objects. It is said that this enforcement creates a contract for the class, and if the condition is not met, the contract has been violated.


What makes Code Contracts special is that you can enable static, compile-time checks (Figure 2) to learn about contract violations already at compile-time. These checks are by default made asynchronously when you compile your application, and error messages are conveniently shown in the Visual Studio Error List window (Figure 3). Both the static checks and runtime behavior can be configured in the properties window for the project. For instance, you can enable or disable runtime checks for Code Contracts.

Note that because of the asynchronous nature of the static checks, you will not immediately see the results in the Error List. Instead, you will have to wait, depending on your project size, around ten seconds to several minutes for the checks to be finished. In the IDE, there is no direct indication (as of yet) that the checks are underway, but you can do this indirectly from Windows Task Manager. Check if the static checker process “cccheck.exe” is running, as it only runs when the checks are underway. The EXE can be found from the Bin directory under the installation path.


Using pre and post conditions is simple to understand and effective, but this where the problem lies in that many code lines are still needed to enforce object state. In fact, pre and post conditions do not help much in reducing the amount of code that you need. Luckily, Code Contracts supports a feature called object invariants, which is an effective solution to the problem.


With object invariants, you can define a single method that contains a set of rules that the whole class must conform to at all times. The method is marked with the special ContractInvariantMethod attribute, through which the Code Contracts engine can find the method. Here is an example:


  [ContractInvariantMethod]
protected void GlobalRules()
{
Contract.Invariant((Percentage >= 0) &&
(Percentage <= 100));

}



With this method in place, static checks are available just like before. At runtime however, the presence of invariants alters the execution of your application slightly. After each call to a public method of the class having contract invariants in place, a second call to the invariant method is injected. This means the invariants are automatically checked without the developer doing anything special. Note however that you have to specifically enable these runtime checks, as calling the invariant checking method introduces overhead to your application. The code injection is done by a special rewriter application called ccrewrite.exe, part of the Code Contracts file set.


In addition to these two basic types of checks (conditions and invariants), there is more functionality in Code Contracts. For instance, the Contracts class in the System.Diagnostics.Contracts namespace (refer to mscorlib.dll version 4.0) contains methods to enforce that array elements have certain properties. Similarly, there is a possibility to configure what happens when exceptions are thrown. This is useful especially when combined with unit tests, as you will learn later. But first a few words about static analysis.


Benefitting from static analysis


If you have the luxury of using any of the Visual Studio 2008 Team System editions like Team Developer or Team Tester (or the equivalent 2010 versions, for that matter), you are already likely familiar with the valuable Code Analysis tool (Figure 4). This tool allows you to statically scan your application’s code, and receive a report of potential issues found regarding areas such as performance, security, globalization, object naming, application design, and so on.

The static analysis provided by Code Contracts is similar in nature: it tries to spot problems before they are noticed at run-time. For instance, if a call to a certain method using pre-conditions would cause the pre-condition to fail, Code Contracts reports about its findings when you build your application.


For instance, assume you had created a class to process numeric data samples and you need to calculate an average value. Your class might look something like this:


  internal class NumericSamples
{
internal int Average(int[] numbers)
{
int sum = numbers.Sum();
int count = numbers.Length;
return sum / count;
}
}


Here, the Average method calculates the average of the samples given as a parameter. Since there is no guarantee that the parameter has a valid set of values, the final division might fail. For instance, the number of samples could be zero (i.e. an empty array was passed), which in turn will cause a division by zero when calculating the average.


Although Code Contracts cannot tell you straight away that this is a possibility, you can indirectly get information that a condition might be violated. The logical check to make sure there are more than zero samples in the array:


  internal class NumericSamples
{
internal int Average(int[] numbers)
{
Contract.Requires(numbers.Length > 0);
int sum = numbers.Sum();
int count = numbers.Length;
return sum / count;
}
}


With this implementation, the method could be called for instance like this:


  NumericSamples samples = new NumericSamples();
int avg = samples.Average(new int[] { 1, 5, 3, 7, 4, 9, 2, 8 });


If you now compile the application with static analysis enabled, the analysis will report success similar to that shown earlier in Figure 3:


  contracts: Checked 1 assertion: 1 correct


This message tell you that the condition in the Average method is always satisfied, and thus the given requirement is met.

Note that sometimes, if you do a regular build in Visual Studio, you might not see the results in the in the Error List window at all. If this is the case, doing a full rebuild instead of a normal build will reveal the results. Be sure to have the Error List visible all the time, as Visual Studio might not pop the window (panel) up automatically especially if compilation succeeds. This happens with the version 1.2.20518.12 of Code Contracts (the version number is visible in the Code Contracts property sheet in project properties).


Now back to the code. To see how Code Contracts can warn you of problems, assume you would change the calling code to this:


  int avg = samples.Average(new int[] { });


With the empty array, the number of samples is zero, and the contract would be violated. If you now (re)build the code, the results will change to these:


  contracts: requires is false
+ location related to previous warning
contracts: Checked 1 assertion: 1 false


Although the error message is not very specific, it shows that the given contract is being violated, and the Line column shows the location where this happens in the code (double-clicking the line will however fail to locate the correct source line, but you can browse the location manually). The line “location related to previous warning” shows the location of the contract check, respectively.


Using Code Contracts in real applications


Using Code Contracts in .NET applications has many potential benefits. Although the .NET implementation of Code Contracts is new and hasn’t been available for long, the concept of Code Contracts is not new. For instance, it has been used in the Java world for a long time already, and is a native part of certain programming languages such as Eiffel and Oxygene. The basics of Code Contracts were investigated in a Microsoft Research project that created the Spec# language. As such, certain best practices have already emerged on how to use Code Contracts and the so- called contract programming.


Effectively using contracts in applications starts from proper architecture design. Contracts are most efficient when combined with loosely-couple objects, which luckily happens to be a common design principle today. On the other hand, deep dependencies between parts of the application make using contracts more difficult, though not impossible.


Many developers and their companies have started using unit tests to have a certain guarantee of the code quality. Code Contracts can be combined with unit tests, but care should be taken to properly manage contract exceptions, which are by default assertion failures. The biggest problem with assertion failures is that they pop up a message box on the screen, effectively stopping the execution of the application until somebody clicks a button on the message box. For the same reasons, running automated unit tests that use Code Contracts would stop at the first contract violation.


Although Code Contracts is still in early stages of development, there are already good solutions to this problem. The easiest way to stop getting assertion failures is to simply uncheck a box in Code Contracts settings. Under the Runtime Checking group, there is a setting called Assert on Contract Failure. Unchecking (removing the mark) changes assertions to regular exceptions, which can easily be handled by the unit tests in Visual Studio (Figure 5). The other way is to create a custom event handler to process the violation.

In addition to tackling the assertion failures within unit tests, you might need to take into consideration the fact that runtime Code Contracts checks are by default disabled. This means that effectively, if you are using unit tests in your code, the contracts might not be checked at all though they exist in the code. Currently, Visual Studio’s own unit testing framework has no understanding of Code Contracts, and thus will not notice if they are missing.

Presently, there is no easy solution to this, but you can leverage the fact that the RuntimeContractsAttribute (defined in the System.Diagnostics.Contracts namespace) attribute is defined in the assembly whenever runtime checks are enabled. For instance, you could then call Assert.Inconclusive if the attribute is not present.


Here is an example of such a check:


  [ClassInitialize()]
public static void MyClassInitialize(
TestContext testContext)
{
Type classToTest = typeof(NumericSamples);
object[] attributes = classToTest.Assembly.
GetCustomAttributes(typeof(
RuntimeContractsAttribute), false);
if (attributes.Length == 0)
{
Assert.Inconclusive(“Code Contracts ” +
“runtime checks are not enabled.”);
}
}


Here, the type information of the tested class (here, NumericSamples) is retrieved, and then the custom attributes of the assembly are fetched. If a RuntimeContractsAttribute does not exist, then the Assert.Inconclusive method is called.


Note that with the current Visual Studio 2010 Beta 1 and the May, 2009 version of Code Contracts, the above code fails to compile if you do enable runtime checks. In this case, the error message will be similar to the following:



The type ‘System.Diagnostics.Contracts.RuntimeContractsAttribute’
exists in both
‘C:Program FilesReference AssembliesMicrosoftFramework.NETFrameworkv4.0mscorlib.dll’
and
‘C:…ContractsTest.exe’


A solution to this is not presently available, but future Visual Studio betas and/or Code Contract versions will surely address the problem.


Conclusion


In this article, you learned about Code Contracts, a new set of classes and routines planned for inclusion in .NET Framework 4.0. Presently, Code Contracts is available on MSDN DevLabs (version 1.2.20518.12 being the latest one at this writing), and is compatible with both Visual Studio 2008 and Visual Studio 2010.


Both Visual Studio versions require you to set up the DevLabs installation package especially for the static check to work. However, it is easier to get started with the latest Visual Studio 2010 beta as no manual assembly references need to be set.


When studying Code Contracts, the main question often becomes: do you really need Code Contracts, or can you live simply with the old Assert method and manual if…throw tests if conditions are not met? The ability of Code Contracts to do static analysis on the code is a very important benefit, and should be used whenever possible. In the current version the static analysis is still somewhat sluggish and not stellar in intelligence, but it is a good start.


At runtime, the behavior of Code Contracts is roughly the same as with exceptions and assertions. This might lead you to think twice about using Code Contracts. However, you should keep in mind that you will then miss the versatility that Code Contracts provides, and also you won’t find a substitute for object invariants. There are already several options that you can customize, and for instance enable only partial rule evaluation at runtime. This can both aid application performance and also help with unit testing.


Presently, the best overall solution seems to combine static Code Contracts analysis with Visual Studio Team System’s Code Analysis. If you can upgrade Visual Studio Professional to a Team Edition, then you will get a wide range of feedback already at compile time. If you additionally have a comprehensive set of unit tests, then you will have a healthy process that is able to deliver quality code with three distinct checks.


But even with a lesser Visual Studio version available, Code Contract can be a highly valuable addition to your defensive programming toolbox. In this light, it’s worth learning well, despite the few pre-release oddities.


Happy contract-based developing!


Resources

Code Contracts on MSDN DevLabs
Code Contracts documentation
Code Contracts on Microsoft Research
Code Contracts in .NET

About the Author


Jani Järvinen is a software development trainer and consultant in Finland. He is a Microsoft C# MVP, a frequent author and has published three books about software development. He is the group leader of a Finnish software development expert group at ITpro.fi and a board member of the Finnish Visual Studio Team System User Group. His blog can be found at http://www .saunalahti.fi/janij/. You can send him mail by clicking on his name at the top of the article.

>

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories