21

I have an object cache which implements the Singleton design pattern. My approach to singleton was always to lazy load the static instance when the property is first accessed.

public static Widget
{
    get
    {
        if(instance==null) instance = new Widget();
        return instance;
    }
}

However, I know that this approach isn't thread safe and the check for instance being null introduces a small inefficiency. Would it be wise to implement a static constructor on the class which instantiates the static instance?

As I understand it, the static constructor would be called whenever the first static property access occurs. Is this valid, and will it provide any benefits over the current lazy load approach or would it be better to explore a proxy implementation, or use a lock to force it to be thread safe?

public static Widget
    {
        get
        {
            if(instance==null)
            {
                lock(padlock)
                {
                    if(instance==null) instance = new Widget();
                }
            }
            return instance;
        }
    }

I don't have a whole lot of experience with static constructors, so don't want to leap in with this idea if it is an equal or worse implementation of the lazy load property.

Cheers, Gary

GaryJL
  • 901
  • 1
  • 11
  • 24
  • 1
    I believe this Q&A thread will give you what you want: http://stackoverflow.com/questions/246710/how-to-implement-a-singleton-in-c – Fredrik Mörk Jul 15 '09 at 14:40

2 Answers2

16

Jon Skeet has a nice article on singletons discussing this issue.

Brad
  • 15,361
  • 6
  • 36
  • 57
jason
  • 236,483
  • 35
  • 423
  • 525
  • This works well with IOC containers too: http://www.tavaresstudios.com/Blog/post/Resolving-a-Singleton-Heres-how.aspx – Mike Post Feb 22 '10 at 04:01
  • The link should be updated to http://csharpindepth.com/Articles/General/Singleton.aspx – Dorus Jun 17 '11 at 09:56
2

Rather than rolling your own threadsafe lazy initializer and possibly getting it wrong, I recommend reading the msdn on Lazy<T>.

https://learn.microsoft.com/en-us/dotnet/framework/performance/lazy-initialization#thread-safe-initialization

Riggeot
  • 89
  • 2
  • 8
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067