I hit a problem recently where a singleton I was calling from an assembly resolver was throwing an exception. It turned out that the sync object used in the lock for the singleton pattern was null. How was this possible? Look at the code below:
using System; public sealed class Singleton { private static volatile Singleton instance; private static readonly object syncRoot = new Object(); private Singleton() {} public static Singleton Instance { get { if (instance == null) { lock (syncRoot) { if (instance == null) instance = new Singleton(); } } return instance; } } }
How can this be, my static readonly field should be set by the field initializer. This should be run before it’s first usage. Normally, this is true but for some reason this was not the case. The C#spec though gives us a workaround, implement a static constructor. The section on static constructors states:
If a class contains any static fields with initializers, those initializers are executed in textual order immediately prior to executing the static constructor.
Therefore, if we add a static constructor to our Singleton class, we get guaranteed initialization of the static field initializers before it is run, also:
The static constructor for a class executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:
- An instance of the class is created.
- Any of the static members of the class are referenced.
Therefore our static constructor will run before our singleton Instance property.