Singleton using static constructor

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • David Veeneman

    Singleton using static constructor

    Why do these questions always come up on Friday afternoon?

    I'm starting to use GoF singleton classes in my projects. Right off the bat,
    I've run into a surprise. I thought that a Singleton could be implemented
    using a static constructor, using code like this, based on version #4 at


    public sealed class MyClass
    {
    private static MyClass m_MyClass = new MyClass();

    static MyClass()
    {
    }

    public static MyClass GetSingleton()
    {
    return m_MyClass;
    }
    }

    According to the C# Language Specification (10.11 Static constructors), a
    static constructor can't be called directly, so I'd use a call like this to
    get the single instance of the class:

    MyClass myObject = MyClass.GetSing leton();

    However, .NET allows me to call the constructor directly:

    MyClass myObject = new MyClass();

    What's more, its allowing me to create multiple objects from the class. So
    the Singleton approach is clearly failing.

    What am I missing? Better yet, what's the simplest thread-safe approach to
    implementing a Singleton in .NET 2.0? Thanks.


    --
    David Veeneman
    Foresight Systems



  • Joanna Carter [TeamB]

    #2
    Re: Singleton using static constructor

    "David Veeneman" <davidv@nospam. com (domain is my last name)a écrit dans
    le message de news: %23pMsViB5GHA.4 00@TK2MSFTNGP02 .phx.gbl...

    | However, .NET allows me to call the constructor directly:
    |
    | MyClass myObject = new MyClass();
    |
    | What's more, its allowing me to create multiple objects from the class. So
    | the Singleton approach is clearly failing.
    |
    | What am I missing? Better yet, what's the simplest thread-safe approach to
    | implementing a Singleton in .NET 2.0? Thanks.

    You forgot to hide the default instance constructor :

    public sealed class MyClass
    {
    private static MyClass m_MyClass = new MyClass();

    static MyClass()
    {
    }

    /////////////////////// don't forget this :-)
    private MyClass() {}
    //////////////////////

    public static MyClass GetSingleton()
    {
    return m_MyClass;
    }
    }

    Also see Jon's comments about thread safety.

    Joanna

    --
    Joanna Carter [TeamB]
    Consultant Software Engineer


    Comment

    • David Veeneman

      #3
      Re: Singleton using static constructor

      Thanks, Joanna--that took care of it. So .NET wasn't calling the static
      constructor--it was calling the implicit public constructor? And adding the
      private constructor prevents the implicit public constructor, so all is
      well. Right?


      Comment

      • Joanna Carter [TeamB]

        #4
        Re: Singleton using static constructor

        "David Veeneman" <davidv@nospam. com (domain is my last name)a écrit dans
        le message de news: uf5se1C5GHA.932 @TK2MSFTNGP04.p hx.gbl...

        | Thanks, Joanna--that took care of it. So .NET wasn't calling the static
        | constructor--it was calling the implicit public constructor? And adding
        the
        | private constructor prevents the implicit public constructor, so all is
        | well. Right?

        Sort of :-)

        If you check out Jon's writings on singletons you will see that there is a
        case for initialising the static field in the static constructor as this is
        guaranteed to be called only once, just before the first call to the
        GetInstance method, therefore ensuring the instance gets created in a
        threadsafe manner. The code that you show doesn't create an instance, so you
        needed to either check for null in the GetInstance method, which is not
        threadsafe, or simply add a call to the instance constructor in the static
        constructor, which is threadsafe.

        Joanna

        --
        Joanna Carter [TeamB]
        Consultant Software Engineer


        Comment

        Working...