Jon Skeet's singleton pattern - questions

M

Marc Pelletier

Hello,

I am still fairly new to CSharp and am trying to implement a singleton
pattern. I found Jon Skeet's excellent page
(http://www.yoda.arachsys.com/csharp/singleton.html), but am struggling a
little to understand it.

The 4th example seems to be the preferred:

public sealed class Singleton
{

static readonly Singleton instance=new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
// this is a private static constructor right?
}
Singleton()
{
// this is a private instance constructor?

}
public static Singleton GetInstance()
{
return instance;
}
}

OK, so if I create a new instance of singleton, like this:
Singleton MyInstance = new Singleton;
there is no public constructor, so nothing will happen?

But if I call Singleton.GetInstance, a new incidence of singleton will be
created (if required ) and returned due to the readonly variable? Could I
declare instance as public static readonly and get rid of GetInstance?

I understand from the body of that page that the private static
constructor is necessary to make the beforefieldinit bookkeeping work
out, but why is the other constructor necessary, since they are both
private? Would there be a scenario, where different code would be
required in either?

Thanks for any illumination.

Marc Pelletier
 
J

Jon Skeet [C# MVP]

Marc Pelletier said:
I am still fairly new to CSharp and am trying to implement a singleton
pattern. I found Jon Skeet's excellent page
(http://www.yoda.arachsys.com/csharp/singleton.html), but am struggling a
little to understand it.

The 4th example seems to be the preferred:

It's certainly preferred by me :)
OK, so if I create a new instance of singleton, like this:
Singleton MyInstance = new Singleton;
there is no public constructor, so nothing will happen?

No - a compiler error will happen. You just can't do it.
But if I call Singleton.GetInstance, a new incidence of singleton will be
created (if required ) and returned due to the readonly variable? Could I
declare instance as public static readonly and get rid of GetInstance?

Yes, although that would limit you in terms of future changes to (say)
the fifth pattern.
I understand from the body of that page that the private static
constructor is necessary to make the beforefieldinit bookkeeping work
out, but why is the other constructor necessary, since they are both
private? Would there be a scenario, where different code would be
required in either?

The private constructor is required solely in order to stop the
compiler from generating a default constructor, which would be public.
 
M

Marc Pelletier

No - a compiler error will happen. You just can't do it.

Right, should have realized that.
Yes, although that would limit you in terms of future changes to (say)
the fifth pattern.
Okay, right, same reason we use properties. I thought so.
The private constructor is required solely in order to stop the
compiler from generating a default constructor, which would be public.

Okay, more bookkeeping. But when the instance variable is created,
which constructor will be called? Where should my constructor code actually
go?

Thanks for all of this, and especially the web page.

Marc Pelletier
 
J

Jon Skeet [C# MVP]

Marc Pelletier said:
Okay, more bookkeeping. But when the instance variable is created,
which constructor will be called? Where should my constructor code actually
go?

There *is* only one constructor - the private one. So that's what will
be called when the instance is created, and that's where you should put
your real constructor code.
Thanks for all of this, and especially the web page.

My pleasure - glad it's useful.
 
G

Guest

What if you need to pass in parameters in to the constructor

Would the 2nd version work? i.e

public sealed class Singleto

static Singleton instance=null
static readonly object padlock = new object()

string server
string db

Singleton(



public static Singleton GetInstance(string db, string server

lock (padlock

if (instance==null

this.server = server
this.db = db
instance = new Singleton(db, server)
return instance





Further more, would the thread-safe instance still work in the Get instance method was overloaded
 
J

Jon Skeet [C# MVP]

markeboy said:
What if you need to pass in parameters in to the constructor.

Then the first thing you need to consider is what happens if the second
time you call GetInstance, you pass in different parameters. It looks
like what you're really after there is the Factory pattern (with
caching) rather than the Singleton pattern. And yes, so long as you
explicitly lock, it will then work (typically with a map from
parameters to created objects).
 
B

bob

Hello,
in the past when I've done this sort of thing (albeit in Smalltalk)
I've simply made the class the singleton and made all methods static.
This seems to remove all problems involving thread safty, but what
problems does it leave?

please explain?

thanks,

bob
 
J

Jon Skeet [C# MVP]

bob said:
in the past when I've done this sort of thing (albeit in Smalltalk)
I've simply made the class the singleton and made all methods static.
This seems to remove all problems involving thread safty, but what
problems does it leave?

If you're going to make all the methods static, there's no point in
making it a singleton in the first place, as you never need to create
*any* instances. The idea of a singleton is that you can use it as an
instance. This means it can implement interfaces usefully, and also you
can decide later to make it *not* a singleton with far less hassle.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top