Search code examples
c#java.netcomputer-scienceinvariants

Do invariant assertions fit into C# programming?


In the book coders at work, the author asks "How do you use invariants in your code". Please explain what this question means.

I saw class invariants on wiki, but the example is in Java and I am not skilled enough in Java to relate this example to C#. .NET 4.0 introduces invariance, covariance, and contravariance and is well explained here. Invariance is so broad. The authors usage of the word seems unit test related. For those that read the book, what does the author mean? Are we talking about making an assumption and simply testing the validity after the unit test?


Solution

  • The word invariant doesn't mean more than something doesn't change under certain conditions. There are many different kinds of invariants. For example in physics the speed of light is invariant under lorentz-transform, i.e. it doesn't change if you change to reference frame. In programming there are many kinds of invariants too. There are class invariants which don't change over the lifetime of an object, method invariants which don't change during the life of a function,...

    A class invariant is something that's always(at least at publicly observable times) true in an instance of that class.

    This is in no way related to co-/contra-variance. Co-/Contra-variance describes which types can be substituted for other types with different (generic) parameters or return types. While you can call something invariant because it doesn't support Co-/Contra-variance this is a completely different kind of invariance than a class or method invariant.

    For example some kind of collection might have the following invariants:

    • data != null
    • Size >= 0
    • Capacity >= 0
    • Size <= Capacity

    With this class:

    class MyCollection<T>
    {
      private T[] data;
      private int size;
    
      public MyCollection()
      {
        data=new T[4];
      }
    
      public int Size{get{return size;}}
      public int Capacity{get{return data.Length;}}
    
      [ContractInvariantMethod]
      protected void ClassInvariant()
      {
        Contract.Invariant(data != null);
        Contract.Invariant(Size >= 0);
        Contract.Invariant(Capacity >= 0);
        Contract.Invariant(Size < Capacity);
      }
    }
    

    Almost every class has some invariants, but not everybody enforces them. .net 4 adds a nice way to document and assert them using code contracts.