HARDCODE

Code, bugs, tools and developers…

Mutants in Your Code

Immutable objects are very popular in concurrency models because immutable objects are naturally thread safe because the state an object cannot be corrupted by multiple threads. As C# developers we can also benefit from immutability. C# has a keyword just for that, readonly. We can also utilize readonly property mechanism with private setters.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// A field assigned in declaration statement
private readonly int _num = 20;

public MyClass(int num)
{
    _num = num; // Assign in constructor
}

// Use a readonly property
public int Num
{
    get{ return _num; }
    private set{ _num = value; } // Or you just don't introduce a private setter
}

These are all good approaches but they don’t accompany you to the depths of API design hell! From now on, I will approach the notion of immutability from another perspective. Classical definition of immutable object says that the object’s state is not changeable after it has been initialized. I find it valuable to be able to change the state of an object after it has been constructed but only once.

readonly keyword ensures that a field can only be assigned where it is declared or in the relevant constructor(static or instance). What if I want a field to be assigned even after it has been instantiated but ensured to be assigned only once?

Readonly properties are phenomenal, I use them everywhere appropriate. But they too don’t solve the problem. Take a look at the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public MyClass()
{
    ...
    Initialize();
}

private void Initialize()
{
    _num = 11; // DON'T EVEN THINK ABOUT CHANGING THIS VALUE!!!
    ...
}

// What if someone else (Better Developer) comes and adds a method to your library like this
// He has enabled users to assign a new value while you assert that you only assign once
public void SomeMethod()
{
    ...
    _num = 12; // I like 12 better(Better Developer)
    ...
}

Readonly property mechanism fails you here, because both the private setter and the backing field is always there to change the state of the object.

What do we do now? We can add an extra boolean field that keeps track of the assignment. But then if you have 5 fields that should be assigned only once, you have to add 5 extra fields to back them up and it would clutter the class definition.

I’ve defined a very basic generic type called WriteOnce for this purpose. Check it out:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    /// <summary>
    /// Objects of this class limits their values to be assigned only once.
    /// After assigning the value the first time, any further assignments will throw exceptions. 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public sealed class WriteOnce<T>
    {
        #region Field

        private T _value;
        private bool _isLocked = false;

        #endregion

        #region Properties

        /// <summary>
        /// Gets/Sets the value
        /// Throws ReadonlyException if assigned for more than once
        /// </summary>
        public T Value
        {
            get { return _value; }
            set
            {
                if (this.IsLocked) { throw new WriteOnceException(); }

                _value = value;
                _isLocked = true;
            }
        }

        public bool IsLocked
        {
            get { return _isLocked; }
        }

        #endregion

        #region Ctor

        public WriteOnce() { }

        public WriteOnce(T value)
        {
            this.Value = value;
        }

        #endregion
    }

WriteOnce ensures that as the developer of a class, you assign a field only once. If you plan to enable users assign values to fields but again only once, you can do that too. Now using this type I can define the previous class like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MyClass
{
    // Will throw WriteOnceException if assigned more than once
    private readonly WriteOnce<int> _num = new WriteOnce<int>();

    public int Num
    {
        get { return _num.Value; }
        set { _num.Value = value; } // Or don't provide a setter if you like
    }

    private void Initialize()
    {
        ...
        this.Num = 11;
    }
}