C# Constructor Gotchas Part 2: Singletons and the Sequence of Initialization

One of my favourite questions to ask interviewees is, “What is the order of initialization in a C# class?”

This is part of a series of posts featuring simple but informative code samples.
You can find a bit of background information and a list of the other posts in the series here.

If the question is too ambiguous, then to be more specific: place the following items in a list according to the order in which they are executed during initialization of a class in C#: static and instance class constructors, and static and instance field initializers.

The simple answer, ignoring inheritance, is:

  • Static field initializers
  • Static constructor
  • Instance field initializers
  • Instance constructor (chain)

If we add in inheritance, then the full order of initialization becomes:

  • Derived class static field initializers
  • Derived class static constructor
  • Derived class instance field initializers
  • Base class static field initializers
  • Base class static constructor
  • Base class instance field initializers
  • Base class instance constructor (chain)
  • Derived class instance constructor (chain)

For extra points, you could point out that before the above listed items, all fields are first initialized to the default value for their type – i.e. reference types are null, integers are zero, etc…

In the previous article of this series, we saw that this sequence differs from some other object oriented languages.
If you find yourself needing to port code from Java or C++ into C#, you would be well advised to study the sequence of class initialization in both languages carefully to ensure that the actual behaviour under initialization is translated correctly, rather than just the literal code steps.

The final aspect to the question of initialization sequence is: under what circumstance does the above sequence not hold true?

The answer is found in some implementations one of the most written about and widely known design patterns – the Singleton.

There’s no need to go into detail about singletons here. Instead, if you want to read more about the various methods of implementation, you can find pretty much all you need to know in the definitive and comprehensive article by Jon Skeet.

For the sake of simplicity we will leave aside inheritance and look at the four step initialization process of a simple class, which (in case you skipped over it above), is:

  • Static field initializers
  • Static constructor
  • Instance field initializers
  • Instance constructor (chain)

What we are interested in here is the exception to this rule. It is possible for the static field initializer to create a new instance of the class in order to assign it to that static field – which is precisely what happens in the fourth example of a singleton implementation in Jon Skeet’s article.

We can demonstrate the sequence and reversal with a very simple example.

First, we have some code which follows the normal sequence of static constructor first, instance constructor second:

From which we see the output:

With a few changes, we can turn it into a singleton:

However, when we run this code, the output is reversed:

In this situation, the static field initializer causes the instance constructor to be called before the static constructor.
If you have a class which performs certain initialization actions in a static constructor and other actions in an instance constructor, and where the instance constructor assumes that the static constructor has executed before it, but then later decide to make a singleton of that class, this is something you should be aware of before it catches you out.

One thought on “C# Constructor Gotchas Part 2: Singletons and the Sequence of Initialization”

Leave a Reply to Sekhar Cancel reply