Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Singleton by Jon Skeet clarification

public sealed class Singleton
{
    Singleton() {}

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

    class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested() {}
        internal static readonly Singleton instance = new Singleton();
    }
}

I wish to implement Jon Skeet's Singleton pattern in my current application in C#.

I have two doubts on the code

  1. How is it possible to access the outer class inside nested class? I mean

    internal static readonly Singleton instance = new Singleton();
    

    Is something called closure?

  2. I am unable to understand this comment

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    

    what does this comment suggest us?

like image 408
amutha Avatar asked Mar 31 '10 06:03

amutha


People also ask

What is singleton in C# with example?

Singleton Class allow for single allocations and instances of data. It has normal methods and you can call it using an instance. To prevent multiple instances of the class, the private constructor is used.

Is singleton thread safe C#?

How to Implement Singleton Pattern in C# code. There are several ways to implement a Singleton Pattern in C#. No Thread Safe Singleton.

How a singleton implementation can be made thread safe?

To make a singleton class thread safe, getInstance() method is made synchronized so that multiple threads can't access it simultaneously.

Why Singleton class is sealed in C#?

Marking the class sealed prevents someone from trivially working around your carefully-constructed singleton class because it keeps someone from inheriting from the class.


2 Answers

  1. No, this is nothing to do with closures. A nested class has access to its outer class's private members, including the private constructor here.

  2. Read my article on beforefieldinit. You may or may not want the no-op static constructor - it depends on what laziness guarantees you need. You should be aware that .NET 4 changes the actual type initialization semantics somewhat (still within the spec, but lazier than before).

Do you really need this pattern though? Are you sure you can't get away with:

public sealed class Singleton {     private static readonly Singleton instance = new Singleton();     public static Singleton Instance { get { return instance; } }      static Singleton() {}     private Singleton() {} } 
like image 107
Jon Skeet Avatar answered Sep 30 '22 10:09

Jon Skeet


Regarding question (1): The answer from Jon is correct, since he implicitly marks the class 'Nested' private by not making it public or internal :-). You might as well do it explicitly by adding 'private':

    private class Nested 

Regarding question (2): basically what the post about beforeinitfield and type initialization tell you is that if you have no static constructor, the runtime can initialize it at any time (but before you use it). If you do have a static constructor, your code in the static constructor might initialize the fields, which means that the runtime is only allowed to initialize the field when you ask for the type.

So if you don't want the runtime to initialize fields 'proactively' before you use them, add a static constructor.

Either way, if you're implementing singletons you either want it to initialize as lazy as possible and not when the runtime thinks it should initialize your variable -- or you probably just don't care. From your question I suppose you want them as late as possible.

That brings met to Jon's post about singleton's, which is IMO the underlying topic of this question. Oh and the doubts :-)

I'd like to point out that his singleton #3, which he marked 'wrong', is actually correct (because lock's automatically implies a memory barrier on exit). It also should be faster than singleton #2 when you use the instance more than once (which is more or less the point of a singleton :-) ). So, if you really need a lazy singleton implementation, I'd probably go for that one - for the simple reasons that (1) it's very clear for everyone that reads your code what is going on and (2) you know what will happen with exceptions.

In case you're wondering: I would never use singleton #6 because it can easily lead to deadlocks and unexpected behavior with exceptions. For details, see: lazy's locking mode, specifically ExecutionAndPublication.

like image 26
atlaste Avatar answered Sep 30 '22 08:09

atlaste