Click here to Skip to main content
15,885,546 members
Articles / Programming Languages / C#

Singletons in C#, Static Constructor vs Static Initialization

Rate me:
Please Sign up or sign in to vote.
4.50/5 (12 votes)
1 Jul 2010CPOL2 min read 66K   16   14
In C#, you can implement a thread safe singleton where the complexity is hidden in the .NET Framework, you do not even need an if statement!

Not a long time ago, I posted an article about how to implement a static constructor. As an example, I used a singleton to show how the static constructor works and how it is implemented. The result was a discussion about singletons, what they are good for and how it can be implemented in C#. There is the standard way (how it is normally done) and also a lot easier way for C# with a static constructor or a static initialization.

The Classic Singleton

C#
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;
      }
   }
}

In every object oriented language (or those I know), a Singleton looks nearly (more or less) like the code above. The Singleton restricts the instantiation of a class to one object. This is provided by a static field which holds the instance. If the instance which is stored in the static field is still null, a new object will be created and assigned to the static variable. The code which does the instantiation is locked so it also works in a multi threaded environment (double check locking). Too much code for you? 

Singleton with Static Initialization

C#
public sealed class Singleton
{
   private static readonly Singleton instance = new Singleton();
   
   private Singleton(){}

   public static Singleton Instance
   {
      get 
      {
         return instance; 
      }
   }
}

C# allows you to initialize the static field directly (and it also works properly)! The instantiation does occur when instance property is called the first time, so it is some sort of lazy instantiation. .NET takes control that it also works in multi threaded environments, so you have nothing to do with it. But you will still have a problem with that solution if you want to execute custom code before instantiation! With a static constructor, you can solve this problem!

Singleton with Static Constructor

C#
public sealed class Singleton
{
   private static readonly Singleton instance;
   
   private Singleton() { }

   static Singleton()
   {
      instance = new Singleton()
   }

   public static Singleton Instance
   {
      get 
      {
         return instance; 
      }
   }
}

It allows you to execute custom code before the singleton is instantiated. But the complexity is still handled by the .NET Framework, so you don't have to implement a double check locking also when you work in multi threaded environments. The static constructor is only executed when the instance property is called the first time. So both variations allow you to implement a thread safe singleton where the complexity is hidden in the .NET Framework. You do not even need an if statement!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
QuestionFor better understanding Pin
vicvis16-Dec-14 23:46
vicvis16-Dec-14 23:46 
GeneralMy vote of 5 Pin
Abhishek Shrotriya31-Oct-14 22:24
Abhishek Shrotriya31-Oct-14 22:24 
Generalnice one Pin
Pranay Rana21-Dec-10 21:41
professionalPranay Rana21-Dec-10 21:41 
GeneralCalss per singleton Pin
Asher Barak11-Jul-10 1:14
professionalAsher Barak11-Jul-10 1:14 
GeneralI'm missing an attribution to John Skeet Pin
jeroenp8-Jul-10 9:59
jeroenp8-Jul-10 9:59 
GeneralMy vote of 4 Pin
johannesnestler7-Jul-10 3:33
johannesnestler7-Jul-10 3:33 
GeneralMy vote of 1 Pin
mavric2126-Jul-10 19:17
mavric2126-Jul-10 19:17 
GeneralJeffrey Richter CLR via C# (second edition) Chapter "The Famous Double-Check Locking Technique" page 642-641 Pin
romgun5-Jul-10 19:37
romgun5-Jul-10 19:37 
GeneralMaybe old wine in new sacs Pin
Rozis2-Jul-10 9:30
Rozis2-Jul-10 9:30 
GeneralRe: Maybe old wine in new sacs Pin
woric5-Jul-10 14:44
woric5-Jul-10 14:44 
GeneralRe: Maybe old wine in new sacs Pin
Jason Christian5-Jul-10 20:14
Jason Christian5-Jul-10 20:14 
GeneralRe: Maybe old wine in new sacs Pin
Rozis6-Jul-10 4:57
Rozis6-Jul-10 4:57 
Thank you for your answer. I red your answer 3 times because i really want to understand it. But help me i still don't get it. Maybe it is because i'm programming in another language and im blind for other solutions... But how my language works is: define a class (write code for it). To use it i call its constructor. The object is created by the runtime system and its constructor is called. As a consequence of that it is completely legal to have a class without a constructor (because the object is actually created by the system, the constructor is no more as an initialization routine). The object is accessable because i saved its reference in a variable. The object is delete when there's not any reference to it anymore. This happens when the variable gets out of scope or when i destroy the object. I do understand the concept of a static constructor.

with this knowledge i would expect we first need a reference to the singleton. The only way i can think of is using new().I guess here i go off the road... But if im right then i could call new() again. Using a static that holds the previous reference will get the desired effect, but that is not what actually happens...

I guess somehow new() is not called at all (from outside the class). Your answer indicates in that direction. Using new() in the static would implicate the object is created at startup by the system (this seems not very OO to me, but ala, bet my language forbids it).

I see the class has a property Instance. How can i access that without having an object reference first? Please feel free to clear my mind...

Thanks,
Rozis
GeneralRe: Maybe old wine in new sacs [modified] Pin
johannesnestler7-Jul-10 3:20
johannesnestler7-Jul-10 3:20 
GeneralRe: Maybe old wine in new sacs Pin
johannesnestler7-Jul-10 3:29
johannesnestler7-Jul-10 3:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.