Singleton Examination (Watch)

  • Thread starter Thread starter Cybertof
  • Start date Start date
C

Cybertof

Hello,


I need some help about a strange thing.
I have the following declaration :


public class CLockeEnv
{
private static CLockeEnv mlockeEnv;

public CLockeEnv()
{
}

public static CLockeEnv GetInstance()
{
if(mlockeEnv == null)
mlockeEnv = new CLockeEnv();
// Returns existing instance in all cases
return mlockeEnv;

}
}


How do you explain than in the 'Locals/Watch' window, i have an infinite
hierarchical tree like :

mLockeEnv
- System.Obkect
- mLockeEnv
- System.Object
- mLockeEnv
- SystemObject
- mLockeEnv
- System.Object
+ mLockeEnv
(etc...infinitely...)


What are all these 'mLockeEnv' ?....do they consume memory ?....i don't
think so as they are not referenced (apart of the first one....), but
why does not the view stop to the first inner level ?


Regards,
Christophe.
 
Cybertof,

They shouldn't. Each instance also shows the static members associated
with the type. Because there is an instance held by the static reference
that you store, when debugging, you can keep going down further and further.

Hope this helps.
 
Cybertof said:
I need some help about a strange thing.
I have the following declaration :


public class CLockeEnv
{
private static CLockeEnv mlockeEnv;

public CLockeEnv()
{
}

public static CLockeEnv GetInstance()
{
if(mlockeEnv == null)
mlockeEnv = new CLockeEnv();
// Returns existing instance in all cases
return mlockeEnv;

}
}

You should be aware that that's not thread safe. See
http://www.pobox.com/~skeet/csharp/singleton.html

See Nick's response to your actual question :)
 
Hi,

One observation
If you are tryig to implement the singleton pattern your constructor should
be private, not public.

Cheers,
 
What about if i let the Constructor public but modifying it like below ?

(instanciating only if no previous instanciation was done, even from
Constructor or from GetInstance method)

public class CLockeEnv
{
private static CLockeEnv mlockeEnv;

public CLockeEnv()
{
if(mLockeEnv == null)
mlockeEnv = new CLockeEnv();
}

public static CLockeEnv GetInstance()
{
if(mlockeEnv == null)
mlockeEnv = new CLockeEnv();
// Returns existing instance in all cases
return mlockeEnv;

}
}
 
Cybertof said:
What about if i let the Constructor public but modifying it like below ?

As it is, you'll end up with a stack overflow the first time you call
the constructor (mlockEnv doesn't get assigned until the "embedded"
constructor call finishes, so the embedded constructor call sees that
mlockEnv is null, and calls the constructor again, etc). Basically, if
you have a non-private constructor you *can't* guarantee that there'll
only be one instance of your class, which is the purpose of the
singleton.
 
That's true.

What about a new 'public' constructor like this :

public CLockeEnv()
{
if(mLockeEnv == null)
mlockeEnv = this; // no more embedded instanciation
}


Note :
*******
No more embedded object instanciation, no stack overflow.
The instance is unique as if it already exists, it does not instanciate
anymore in the constructor, but the first time it was, it flags
mLockeEnv saying 'i'm existing'.
So, apart of thread safety aspect, the singleton can see its constructor
called many times, but only the first time is the first creation of the
object (using the new keyword), or passing through the GetInstance()
method.


(final code)

public class CLockeEnv
{
private static CLockeEnv mlockeEnv;

public CLockeEnv()
{
if(mLockeEnv == null)
mlockeEnv = this;
}

public static CLockeEnv GetInstance()
{
if(mlockeEnv == null)
mlockeEnv = new CLockeEnv();
// Returns existing instance in all cases
return mlockeEnv;

}
}
 
Cybertof said:
What about a new 'public' constructor like this :

public CLockeEnv()
{
if(mLockeEnv == null)
mlockeEnv = this; // no more embedded instanciation
}

That would certainly avoid the recursion.
Note :
*******
No more embedded object instanciation, no stack overflow.
The instance is unique as if it already exists, it does not instanciate
anymore in the constructor, but the first time it was, it flags
mLockeEnv saying 'i'm existing'.
So, apart of thread safety aspect, the singleton can see its constructor
called many times, but only the first time is the first creation of the
object (using the new keyword), or passing through the GetInstance()
method.

No, an object is *always* created when the constructor is called - the
fact that you're in the constructor gives that!

Why are you desperate to avoid making the constructor private?
 
Hi,

Why no make the constructor private and all the problems gets away?

What you have agains it?

That's the only way to be sure that it will be created only once, that is
the whole point of the singleton !!!

Cheers,
 
Back
Top