A Handful of Singletons in C#

Recently I was involved in an interview where I was queried on the Singleton Creational design pattern.
I thought I’d share what I came up with.
In order of preference from most to least used.

Most used:
System.Lazy introduced in .Net 4.0
Sealing the class can help the Just In Time (JIT) compilation to optimise the IL.
Of course you also don’t want your singletons being extended,
but the fact that your constructor is private and default (takes no arguments),
guards against instantiation and sub-classing

Example 1

public sealed class KimsSingleton {

   // System.Lazy guarantees lazyness and thread safety
   private static readonly Lazy<KimsSingleton> _instance = new Lazy<KimsSingleton>(() => new KimsSingleton());

   // private, preventing any other class's from instantiating.
   // Also prevents creating child class's... which would create another instance, thus violating the pattern.
   private KimsSingleton() {
   }

   // static so client code can call Instance property from class.
   public static KimsSingleton Instance {
      get {
         return _instance.Value;
      }
   }
}

.Net guarantees lazy initialisation if the type is not marked with beforefieldinit.
Although it could be more lazy. See example 3 for one way to do this.
Marking the types constructor as static tells the compiler not to mark the type with beforefieldinit in the IL,
thus giving us laziness.
This is also thread safe.
In C#, static constructor will execute only once (per AppDomain),
either on instantiation, or when a static member is referenced for the first time.

Example 2

public sealed class KimsSingleton {
   private static readonly KimsSingleton _instance = new KimsSingleton();

   static KimsSingleton() {
   }

   private KimsSingleton() {
   }

   public static KimsSingleton Instance {
      get {
         return _instance;
      }
   }
}

Example 3

public sealed class KimsSingleton {
   private KimsSingleton() {
   }

   public static KimsSingleton Instance {
      get {
         return Nested._instance;
      }
   }

   private class Nested {
      static Nested() {
      }
      // This gives us more laziness than than example 2,
      // because the only static member that can initialise is the static instance member in Nested.
      internal static readonly KimsSingleton _instance = new KimsSingleton();
   }
}

One more way that I’ve seen used quite a few times that starts to fall apart.
Even the GoF guys do this example.
Head First Design Patterns do it as well (not good!),
although they use the volatile keyword which helps.
Lets look at where it falls apart.
If performance is an issue, stay away from this way.
If you fail to declare your instance member as volatile,
the exact position of the read / write may be changed by the compiler.
I don’t use this method.

Example 4

public sealed class Singleton {
   private volatile static Singleton _instance;
   private static readonly object _lock = new object();

   private Singleton() {
   }

   public static Singleton getInstance() {
      if (_instance == null) {
         // Lock area where instance is created
         lock(_lock) {
            if (_instance == null) {
               _instance = new Singleton();
            }
         }
      }
      return _instance;
   }
}

There are quite a few other ways of implementing the singleton.
Many of which are flawed to some degree.
So I generally stick with the above implementations.

Tags: , ,

15 Responses to “A Handful of Singletons in C#”

  1. Restuta Says:

    Article on similar topic from John Skeet with much more details http://csharpindepth.com/Articles/General/Singleton.aspx

  2. binarymist Says:

    Do you mean Jon Skeet?
    Yeah, He’s a wealth of information.
    Generally pretty accurate too.

  3. Restuta Says:

    Yes, “Jon”, I mistakenly added “h”. He hates that =) What do you mean “generally”, what is inaccurate?

  4. Steve Russell Says:

    Hi. You say that Example 4 “falls apart”. Can you explain how this happens, exactly? Thanks.

    You also say it has poor performance. Given that it’s designed to improve performance compared to a naive thread-safe, I’m interested in what performance improvements can be made on Example 4. Do you have any benchmarks?

    Thanks!

  5. Steve Russell Says:

    Hi again

    I’m confused by your “most used” claim regarding the Lazy generic in .NET 4. It’s a new, and very obscure, feature. How could it suddenly become “most used”.

    And I’m also interested in your answer to Restuta’s question: what inaccuracies has Jon made?

    Thanks!

  6. binarymist Says:

    I thought I did?
    “If you fail to declare your instance member as volatile,
    the exact position of the read / write may be changed by the compiler.”

    The instance member may be null when you perform the check,
    but, there is no guarantee that the null check will occur where you think it will.
    If it doesn’t, you could be newing a Singleton that’s already been instantiated.

    Intel’s x86 and x64 processors always apply acquire-fences to reads and release-fences to writes…
    whether or not you use the volatile keyword.
    Other processor vendors don’t supply such guarantees.
    This is all good, but…
    volatile does have an effect on optimizations performed by the compiler and the CLR.
    This is independent of hardware of course.
    what does this mean?
    Reads and subsequent writes can be swapped.
    Writes and subsequent reads can be swapped.

    On the performance:
    Example 4 can not be optimised as the previous examples can be due to marking the _instance with volatile.
    Plus there is the chance of blocking.
    Ofcourse, this depends on how performant you need the code to be,
    but Example 4 has the potential to be slower than the previous examples.

    Check out Joseph Albahari’s comments here http://www.albahari.com/threading/part4.aspx#_The_volatile_keyword

    The performance improvements to Example 4 are Examples 3 and above.
    No benchmarks. Feel free to benchmark.
    As stated, these were just interview answers.

    “I’m confused by your “most used” claim regarding the Lazy generic in .NET 4. It’s a new, and very obscure, feature. How could it suddenly become “most used”.”

    As I said…
    I thought I’d share what I came up with.
    In order of preference from most to least used.
    I don’t see how Lazy is very obscure.
    It’s very easy to find.
    It has become most used… because I use it the most out of the other examples.

    In regards to Jon inaccuracies.
    I said “Generally pretty accurate too”. Take this how every you will.
    I’ve learnt quite a bit from Jon, so I’m not about to go and look for inaccuracies.

    Hope this helps.

  7. Steve Russell Says:

    Hi

    Thanks for your response.

    You’re right that leaving out “volatile” breaks Example 4. But that’s hardly the implementation “falling apart”, IMO: volatile is there for a good reason.

    The performance hit from volatile can be avoided by the use of an explicit memory barrier, or an interlocked compare/exchange, which is pretty much how the thread safety of static initialisers is implemented. But then, as you say, why not let the language do it for you -> Example 2.

    I misunderstood what you met by “most used”. I thought you meant by the community. I now understand that you mean by you.

    Thanks again.

  8. Cade Roux Says:

    This is a generic one I use. It\’s a base class, so you rarely have to implement again: http://www.semicolon.net/2009/06/my-c-generic-singleton-base-class.html it has lazy instantiation, doesn\’t require a public constructor, etc.

  9. Joe Gaber Says:

    This might be a real neophyte question, but why would you ever write an application these days without an IoC framework, which all of the ones I know manage singletons in the container? Are there situations where the IoC container can’t provide the singleton instance needed and you are forced to write your own? I might have missed something, but I haven’t seen a singleton written in any of the dozens of apps I’ve been involved in for 8 or 9 years. Maybe my apps are not complex enough. Can someone justify the use case for hand writing singletons?

  10. binarymist Says:

    Joe:
    Often small apps don’t require the overhead of an IoC container.
    Often developers inherit legacy software that doesn’t have an IoC container for what ever reason, but the fact still exists and is outside of our control.
    The last place I worked at was full of university graduates that had written large complex projects without the help of any IoC frameworks.
    It was full of static classes. I was brought in to retrofit unit tests.
    An IoC container was one of the first things I said we needed.
    The manager wasn’t interested, so I had to try and make the mess testable. I started by replacing the static classes with singletons and implementing poor mans DI.

    I used a Singleton in my PowerOffUPSGuests application.
    Namely ServerAdminDetails.
    It provides a Queue of ServerAdminDetails.
    I use PowerShell to instantiate the library on a power off event from the UPS, and really didn’t want any external dependencies.
    So IoC containers where out.
    The library is very light weight.
    In this instance, the Singleton was a perfect fit for the problem at hand.

    You can check the usage of the Singleton at http://code.binarymist.net

  11. Joe Gaber Says:

    @binarymist, yes, I can see these situations having some affect; however, if you are using a IoC container like Pico on the Java side or StructureMap on the .Net side, they are so lightweight that I wouldn’t even think you’d have to ask anyone about it, just use it and only use it in the places you have to update/modify. But every situation is different, I do know that. One other thing is that for most of the last 15 years, my main task has been educating management of better ways of doing things. Many good technologists don’t feel comfortable in this role so that can be a hinderance to getting them to see the alternatives.

  12. binarymist Says:

    Yeah, understand the educating management.
    I think it was more of a “management didn’t feel comfortable taking suggestions from someone under them”.
    The situation was made worse by the fact that my manager was 10 years younger than me with less experience also.

  13. Joe Says:

    Gah! This is what happens when people get their hands on a shiny architecture. They start implementing things “without asking permission.”

    In our company, we almost exclusively use service oriented applications. If someone came in and implemented structure map throughout one of our apps, it would be supremely irritating.

    Soa apps don’t play well with constructor injection. Instead, we typically use service locator injection.

    Someone assuming they could just replace all of that during maintenance, without asking permission would quickly be looking for a new job.

  14. binarymist Says:

    I can understand the irritability of someone changing the architecture without communicating with the interested parties.
    I also understand that pearls are created from irritations.
    So, because someone does something irritating doesn’t necessarily mean it’s bad, in fact often it ends up being a pearl.

    I’m a little confused by your statement that SOA applications don’t play well with constructor injection, but you think the service locator pattern is somehow superior?
    Could you provide some more context?

    I’ve used both in the past.
    the Service Locator is an anti pattern.
    It violates the Hollywood principle (Don’t call the container, it’ll call you).
    It violates the Principle of least astonishment.
    It violates the Command-Query Separation principle.

    Developers need to understand far more about the application than they should have to, in order to use the Service Locator.
    DI makes for easier testing.

    The DI Pattern is a much cleaner approach than the Service Locator.

    Mark Seemann says it better than I could here.
    Martin Fowler also compares the two patterns here.

  15. David Clayton Says:

    From a design perspective I am always wary of singletons, they generally make unit testing hard and create tight coupling in your code in the same way that instantiating objects does. Misko Hevery from Google has some very good explanations as to why.

    http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/

    If you really must use a singleton if it implements an interface and you inject it then you can mitigate these problems.

Leave a reply to Steve Russell Cancel reply