As you can see from my nickname I'm newbie actually learning about Singleton pattern, where I got one problem. Before I've learned that static constructors are always executed before the standard constructors, but in this code below, the result is different, first I see the "Insta" string then the "Static", why does it happen ?
sealed class Singleton
{
private static readonly Singleton instance;
private Singleton()
{
Console.WriteLine("Insta");
}
static Singleton()
{
instance = new Singleton();
Console.WriteLine("Static");
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
class Program
{
static void Main()
{
Singleton s1 = Singleton.Instance;
}
}
If you will write
static Singleton()
{
Console.WriteLine("Static"); //THIS COMES FIRST
instance = new Singleton();
}
you would see what you expect
static ctor is executed at first, as expected, but you print on console after the
instance = new Singleton();
line, but this line execute instance ctor, so "inst".
So execution flow:
- static ctor
instance = new Singleton();
- instance ctor prints "insta"
- "static"
See the MSDN pattern here for a quality explanation of the singleton pattern.
MSDN recommends you should write it as below so it is thread safe:
using System;
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
By the way, this pattern has the following advantage over static constructor:
The instantiation is not performed until an object asks for an instance; this approach is referred to as lazy instantiation. Lazy instantiation avoids instantiating unnecessary singletons when the application starts.
See if this feets your need, and if so, implement this solution.
The static method is invoked first. Here's the proof--change your code to the following:
static Singleton()
{
Console.WriteLine("Static method start");
instance = new Singleton();
Console.WriteLine("Static method end");
}