Published: 21 Oct 2009
By: Dino Esposito

In this article, I'll go through the concept and implementation of class invariants as supported by the .NET Framework 4 Code Contracts API.

Contents [hide]

The Code Contracts Series

  • Code Contracts Preview: Preconditions  In this article, Dino Esposito reviews code contracts in .NET using sample Visual Studio 2008 applications.
  • Code Contracts Preview: PostConditions In this article, I'll focus on another aspects of Code Contracts - postconditions. Before going any further, though, let me briefly summarize some of the design choices the team made to expose the Code Contracts API.
  • Code Contracts Preview: Invariants In this article, I'll go through the concept and implementation of class invariants as supported by the .NET Framework 4 Code Contracts API.
  • In the .NET Framework 4, Code Contracts will offer you a powerful way to programmatically declare what kind of software contract your class is fulfilling. Admittedly, the expression "programmatically declare" may sound like an oxymoron. If it is "programmatic", then it is mostly about doing; if it is "declarative" then it is mostly about telling. With Code Contracts, you will actually use programmatic instructions to tell which conditions your class will need to meet before and after execution.

    A Code Contract is made of a number of elements. Some apply to individual methods such as preconditions and postconditions. Some, instead, apply more to the class as a whole. This is the case of invariants. In this article, I'll go through the concept and implementation of class invariants as supported by the .NET Framework 4 Code Contracts API.

    The discussion is still based on the preview of the API offered by the .NET Framework 4 Beta 1.

    What’s an Invariant, Anyway?

    Generally speaking, an invariant is in software terms a predicate that holds true before and after the execution of a sequence of operations. In Code Contracts, an invariant is a Boolean expression that returns true before and after the execution of each public method of a class. This variation of an invariant is also referred to as a class invariant.

    A class invariant identifies conditions that the class must fulfill constantly during its lifecycle. A class invariant also represents a set of constraints for the state of any instance of the class. Class methods are responsible for preserving all of the invariants during the lifetime of a class instance.

    Should all methods be responsible for preserving any invariants? Well, not necessarily.

    What's really important is that all public methods of the class preserve all of the invariants at any time. It is anyway acceptable that protected and private methods sometimes break invariant conditions temporarily as they strive to achieve certain results. This practice is not generally encouraged, but it is acceptable as long as no other (simple) solution exists or may be found.

    The Code Contracts API in the .NET Framework 4 establishes class invariants right after the call to the constructor and checks fulfillment before and after each public method call. A quick example of an invariant is the fact that the class is required to stay constantly in a valid state according to the validation rules set for it. Consider, for instance, a class that belongs to an entity/relationship model. You annotate this class with some validation attributes on its properties. Depending on the values effectively assigned to each property in an instance of the class, the resulting may or may not be valid. In some cases, it may be required that the class is constantly in a valid state except, perhaps, temporarily during internal, private operations. The Code Contracts API provides you with the tools to declare this condition nicely and have it enforced strictly.

    Let's explore then the syntax of invariants.

    Implementing Invariants

    Class invariants are named Object Invariants in the Code Contracts jargon. All invariants are grouped in a single place for each class. This place is a method arbitrarily named and decorated with the ContractInvariantMethod attribute.

    Although not mandatory, it is rather recommended that you mark the invariant method as protected to avoid accidental calls from top-level code.

    It is not permitted to have multiple methods in a class decorated with the ContractInvariantMethod attribute. The invariant method is required to be void and parameterless. If you miss any of these conditions, you'll get runtime exceptions as soon as the invariant is invoked. The first time the invariant is invoked is when the constructor of the class is called.

    How would you specify invariant conditions?

    The body of the invariant method will typically contain the specification of the invariant conditions. To specify an invariant condition you use the Invariant method on the Contract class:

    The Invariant method gets a Boolean expression that involves the members of the class and throws an exception if the condition is false. All invariants for a class are listed sequentially.

    Unlike other types of software contracts, the method Invariant can be preceded by plain code. The body of the contract invariant method can then contain both plain code and invariants. I'll just use this possibility to briefly track the chain of calls for an invariant.

    Tracking the Chain of Calls

    Suppose you have a piece of code like below. A new Customer instance is created and its ID property is set to 3. Next, a class derived from Customer is instantiated and one of its public methods is called.

    The Customer class has the following invariant method:

    For debugging purposes, I'm assuming that each public method in the Customer class (including public property setters) stores its name into a protected member of the class named lastMethod, as shown below.

    Figure 1: Chain of calls for invariants.

    Chain of calls for invariants.

    Figure 1 shows the resulting chain of calls. The invariants are checked during the construction of the class and after the call of any public member.

    Invariants and Inheritance

    You may notice that the invariants are checked twice during the construction of a derived class. This is obviously due to the fact that constructor calls are chained. However, it also means that invariants are inherited - this is much more significant from the perspective of Code Contracts. The derived class, in fact, inherits all the invariants of the parent class and may add its own ones. Having the class a set of invariants it forces the check upon construction.

    As you have seen earlier, the method decorated with the ContractInvariantMethod attribute is commonly declared as a protected member. This is a form of caution to avoid inadvertent calls from the main stream of code.

    You could even add the virtual modifier to the method if that suits you. You can't change the method's modifier to private instead. If you use the private modifier you will get a compile error because, quite simply, an invariant method is not allowed to be private otherwise it won't be visible in a derived class.

    In case of inheritance, invariants are summed up as logical predicates using the AND operator. This means that the invariant conditions a derived class should fulfill may be stricter than the conditions set for the base class. This may be a problem when you consider what it means to be a derived class in object-oriented applications. A derived class inherits scope and behavior from the parent class. If defined, it also inherits invariants. So a derived class may not be able to use the entire inherited scope to avoid breaking some of the new invariants set.

    Invariants and Class Design

    The collection of invariants identifies conditions that contribute to keeping the class instance in a consistent state. Finding invariants is a process commonly intertwined with class design. While you could add invariants at any time during the development stage, it is highly recommended that you start adding invariants since the very beginning.

    Fact is, if you know what the class is doing and how it has to be accomplished, then you also know what its invariants are. It should also be noticed - and it is not a secondary point - that not all classes need invariants and that not having invariants is not necessarily a sign of bad design.

    The only situation that should worry you is when you don't know what your invariants are. It is acceptable that you deliberately decide not to implement invariants in a class. It is likewise acceptable that a given class - usually a simple class with little or no behavior - doesn't have any invariant condition. It is not acceptable that you can start coding a class without having clear what its invariants are. Invariants are not a possibly volatile thing like functional requirements. If you know the expected behavior of a class, then you know about its invariants, if any.

    This said, adding known invariants for a class at a later time may be problematic. Invariants, if they are added since the beginning, help to keep the code aligned to the right track and, in a way, slow down the natural biodegradability of classes and the drift towards deterioration of design.

    In other words, invariants ensure that the state remains consistent as you add behavior to a class. Without invariants in the code since the beginning, addition of behavior may inadvertently break consistency while not preventing successful compilation and runtime execution. You may end up with nasty corner cases and can hardly attach invariants. However, all in all, this would just be the least. In such cases, the real negative aspect is that the inability to attach invariants is the proof that your class design is less than optimal.

    <<  Previous Article Continue reading and see our next or previous articles Next Article >>

    About Dino Esposito

    Dino Esposito is one of the world's authorities on Web technology and software architecture. Dino published an array of books, most of which are considered state-of-the-art in their respective areas. His most recent books are “Microsoft ® .NET: Architecting Applications for the Enterprise” and “...

    This author has published 54 articles on DotNetSlackers. View other articles or the complete profile here.

    Other articles in this category


    Android for .NET Developers - Location and Maps
    In Windows Phone and iOS getting the current position of the device in terms of latitude and longitu...
    Android for .NET Developers - Using Web Views
    In this article, I'll show a native app that contains a web-based view. The great news is that HTML ...
    Android for .NET Developers - Building a Twitter Client
    In this article, I'll discuss the features and capabilities required by an Android application to ta...
    Developing a Hello World Java Application and Deploying it in Windows Azure - Part II
    In this article we will see the steps involved in deploying the WAR created in the first part of thi...
    Ref and Out (The Inside Story)
    Knowing the power of ref and out, a developer will certainly make full use of this feature of parame...

    You might also be interested in the following related blog posts


    Foxit PDF Previewer update read more
    Winforms Release History : Q2 2009 SP1 (version 2009.2.9.729) read more
    Thoughts on the Code Contracts Preview for .NET 4.0 read more
    ASP.NET MVC Source Refresh Preview read more
    Updated to MS Ajax RC read more
    Top
     
     
     

    Please login to rate or to leave a comment.