No Interface without Contract? – Part 6: Object Invariants

Invariants are a kind of postconditions which apply to all members. How to formulate them using Code Contracts?

In the previous part we got started using Microsoft Code Contracts and formulated first pre- and postconditions. We only looked at “simple” ones. In this posting you will learn what object invariants are and how they are connected with Code Contracts.

What are Invariants?

As anticipated in the introduction, invariants can be compared to postconditions valid for all members of a class. In fact, you are actually able to modulate them using Contract.Ensures(invariant) in each member.

However, they are more than simple postconditions – they are always valid, regardless of the object’s state. So invariants must never be broken during an object’s lifetime. Thus, other members can rely on them like on preconditions.

Take a look at the formal definition from Wikipedia:

In computer science, a predicate that, if true, will remain true throughout a specific sequence of operations, is called (an) invariant to that sequence.

This definition describes quite well what an invariant is. Just one thing: In the following we will understand the condition itself which must always be true as “invariant”.

A simple invariant would be that the Age property of a class Person is always greater equal zero. Another one could be that a private field holding a reference to a FileStream in a FileLogger is not null.

How to formulate invariants?

Code Contracts has built-in support for invariants. Section 2.3 of the Contracts Manual says:

All of an object’s invariants should be put into a nullary instance method that returns void. If the
class isn’t sealed, then the method must be protected. That method is identified by being marked with the
attribute [ContractInvariantMethod] (Section 4.2). The invariant method must have no other code in it than a
sequence of calls to Contract.Invariant .

For us, this means that we just have to create a method with a arbitrary name and decorate it with the ContractInvariantMethod: If our class is sealed, we will make it private, otherwise protected.

[ContractInvariantMethod]
private void FooInvariant()
{
    Contract.Invariant(this.bar != null);
}

Sub classes may also define their own contract method – it may even have the same name as the one from the base class. However, manually calling the invariant method is never necessary.

Realization

The rewriter will now inject calls to the invariant methods into every public member. In addition, a check is performed, whether there are recursive calls (etc.) so you can call public members in the Contract.Invariant blocks.

Why invariants?

Invariants complete the idea of pre- and postconditions on an “object wide level”. So the advantages of them also apply on invariants: Clarifying interfaces (and also parts of the implementation).

By writing them down using Code Contracts you take care that other developers changing your code won’t break your idea of “valid” values for fields and properties.

Invariants are the “last chance” to avoid objects being in an invalid state. If one fails, there is definitely something wrong with your code. So there should exist preconditions being strict enough to avoid invariant violations.

Common Invariants

Very common invariants are those which require fields having non-null values. Numeral variables which have to move within a given range are a common usage scenario, too.

Example

Let’s take at a little example: A person.

Note: It may be a little bit uncomfortable to write duplicate code in the invariants and in the setters. This, however, is currently necessary as the rewriter does not automatically generate Contract.Requires calls out of invariants. However, the part after the next will introduce an attribute which allows us to leave away the Contract.Ensures in the getters.

public sealed class Person
{
    private string name;
    private int age;

    public string Name
    {
        get
        {
            Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()));

            return this.name;
        }
        set
        {
            Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(value));

            this.name = value;
        }
    }
    public int Age
    {
        get
        {
            Contract.Ensures(Contract.Result<int>() >= 0);

            return this.age;
        }
        set
        {
            Contract.Requires<ArgumentException>(value >= 0);

            this.age = value;
        }
    }

    [ContractInvariantMethod]
    private void ObjectInvariant()
    {
        Contract.Invariant(!String.IsNullOrEmpty(name));
        Contract.Invariant(age >= 0);
    }
}

Conclusion / Outlook

Although they are not as important as pre- and postconditions, object invariants complete their idea. Code Contracts support them directly.

The next part will talk about interfaces and abstract classes and ways to formulate contracts for them, later we will talk about some advanced features of Code Contracts including the static checker.

DotNetKicks Image
About these ads

One Response to “No Interface without Contract? – Part 6: Object Invariants”

  1. DotNetShoutout Says:

    No Interface without Contract? – Part 6: Object Invariants…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…


Comments are closed.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: