C# – When to use [Pure] on a constructor

ccode-contractsnetpure-function

I'm learning about code contracts in .NET, and I'm trying to understand the idea of pure constructors. The code contracts documentation states:

All methods that are called within a contract must be pure; that is, they must not update any preexisting state. A pure method is allowed to modify objects that have been created after entry into the pure method.

And the PureAttribute documentation states:

Indicates that a type or method is pure, that is, it does not make any visible state changes.

I understand these statements when it comes to methods, but what about constructors? Suppose you had a class like this:

public class Foo
{
    public int Value { get; set; }

    public Foo(int value) {
        this.Value = value;
    }
}

This constructor obviously does affect the state of the new Foo object, but it has no other side effects (e.g. it doesn't manipulate any of the parameters or call any non-pure methods). Is this a candidate for [Pure] or not? What is the significance of placing a [Pure] attribute on a constructor, and when should I do this in my own code?

Best Answer

You decorate a method with [Pure]:

  • If the method doesn't have side effects. For example, if the method accesses a database and modifies it or its result depends on the database, it's not pure.

  • And if you expect to use it in code contracts. For example, if the method is pure, but you have no intention to use it in code contracts, adding [Pure] would have no benefit and won't make your code faster.

As far as it concerns constructors, it looks like they are assumed to be pure in .NET and don't need an explicit attribute. I looked at several constructors in .NET Framework source, such as DateTime, and they don't have [Pure] attribute.

I suppose this is done for several reasons:

  • It may be too impractical to have to write a parameterless constructor with [Pure] attribute just to be able to use the class/struct in a contract.

  • Some, such as String, don't have explicit constructors.

  • The constructors receive special treatment even outside code contracts; for example, you're not expected to throw exceptions inside them.

  • [Pure] is just a convention which is here to simplify your life, but there is no actual static checking to ensure that the method decorated with this attribute is pure. void DestroyDatabase() may be decorated as being pure, and code contracts won't notice anything wrong.

    Currently there is no component of Code Contracts which checks if methods declared pure are pure indeed. Thus if a programmer decorated a method with [Pure], it’s just believed.

    From Code Contracts #5: Method purity

  • .NET Framework itself contains constructors which are not pure. For example, List<T>(IEnumerable<T> collection) is actually impure if looping through the collection has side effects.

  • Contracts shout be kept simple. I can easily imagine a contract such as Contract.Requires(!string.IsNullOrEmpty(name)), so there are good reasons to declare the static string.IsNullOrEmpty pure.

    On the other hand, if you need a StringBuilder in order to build the string you'll check then for something by calling an instance method of your business class, you're probably misusing the contracts. That's also why StringBuilder.ToString is not marked as pure, even if it might be (is it?)