Skip to content

The Singleton Pattern in C#

10 May 2009

What

The singleton pattern is used to restrict a class to a single instance. This is useful when some global state is required across the application or when a single instance of the class is sufficient and multiple instances are not desired – for example the class consumes a lot of resources. The singleton is implemented with a private constructor to prevent outside instantiation and a static method (or property) that creates and returns the unique instance when called.

Why

When implementing a singleton in C#, a natural question arises: why use a singleton instead of a static class? It is true that a static class accomplishes the same thing – provides a single instance of the class. The difference comes from the fact that static classes cannot implement any interfaces and can only derive from the base Object class.

Sometimes it is needed for the class to implement a certain interface. In these cases, singletons become useful because they don’t have these limitations.

staticvssingleton

It is true that a static class implementation is cleaner and easier to use than a singleton, as it can be seen above. We can use Processor.Process() with the static class while the singleton is called using Processor.Instance.Process(), not to mention that the static class doesn’t need the private attribute and doesn’t have to explicitly declare a private constructor. Still, the following can’t be implemented using static classes:

derivedsingletons

Both OnlineProcessor and OfflineProcessor unique instances can be passed as Processor objects.

How

A simple C# implementation of a singleton looks like this:

public sealed class SingletonClass
{
    private static readonly SingletonClass instance = new SingletonClass();

    private SingletonClass() { }

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

For a more detailed explanation, visit MSDN.

Although the constructor doesn’t do anything, it is important to declare it as private to hide it from the outside code. When the constructor is declared as private, the class cannot be instantiated from outside itself.

The static readonly attribute holds the unique instance. Note that declaring it this way ensures lazy instantiation – the object will be created at runtime only when it is first referenced. The static Instance property is used to retrieve the instance by the outside code (SingletonClass.Instance).

Finally, the class is declared as sealed. On MSDN it is stated that this will prevent other classes to derive from this class and possibly duplicate the instance. The truth is that as long as all class constructors are declared as private, other classes won’t be able to derive from it. This happens because during instantiation constructors have to be called for all classes in a hierarchy starting from the top-most class and this won’t be possible from a derived class as long as all its parent’s constructors are private. It is still good practice to seal the class to make it obvious that it is not meant to be derived from (plus there is a gain in performance when calling virtual methods on a sealed class).

Singletons can be implemented based on this skeleton. Additional methods and properties shouldn’t be static, as they can only be accessed through the Instance property. This is the mechanism by which singletons can implement interfaces or be derived from any class.

Note that this simple implementation is not thread-safe as two threads could simultaneously reference the Instance property and, because of this, receive different objects. Again, look on MSDN for thread-safe implementation considerations.

From → code complete

2 Comments
  1. M. Hudson permalink

    Thanks for you sharing. It’s make me clarify.

  2. vladr permalink

    I’m glad you found it useful.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: