Singleton problem

T

ThunderMusic

Hi,
I have a problem regarding singletons in C#. What I would like to do is the
following

ClassA is a singleton
ClassB inherits from ClassA and is also a Singleton
there cannot and instance of ClassA and an instance of ClassB, there must be
only one of one or the other...

Is there a way to do it? or it's simply not possible?

I tried to put the m_instance member variable protected, so the inherited
classes can see it, but the problem is when I have the method Instance(), it
returns the instance of ClassA, not the instance of classB, and if I
override it, I can't change it's return type... Is there a way to shadow the
original method which returns ClassA to replace it with a method that
returns ClassB?

Thanks

ThunderMusic
 
B

Brian Gideon

ThunderMusic,

To do that ClassA must not be marked as sealed or have a private
constructor. That pretty much makes it impossible to guarentee that
there will be one and only one of ClassA or any of its subclasses.

Have you looked into using one of the factory design patterns? Maybe
one would be better suited for your problem.

Brian
 
B

Bruce Wood

ThunderMusic said:
Hi,
I have a problem regarding singletons in C#. What I would like to do is the
following

ClassA is a singleton
ClassB inherits from ClassA and is also a Singleton
there cannot and instance of ClassA and an instance of ClassB, there must be
only one of one or the other...

Is there a way to do it? or it's simply not possible?

I would move toward a type of Factory pattern, where you have a Factory
method that creates either an A or a B on the first request (depending
upon arguments passed) and then from thereon in returns the same
instance over and over again.

I see what you're trying to do: really you have two factory "methods":
A.Instance and B.Instance, and you want the first one called to
allocate the instance and then from then on both return the same thing:
the originally allocated instance. However, don't you think that
callers will find this confusing? It looks like two singletons, but
they're not really independent singletons.

I would find it easier to understand this:

A whatever = B.GetMeWhatINeed(...);

where "whatever" ends up being either an A or a B, and then always
returns the same object after that. Easier to program, easier to
remember what's going on, IMHO.
 
T

ThunderMusic

ok, here's the real deal... I have a Client and a Server Class and the
Server is also a Client of it's own network and does exactly all the same
things that Client does plus some other things... But I don't want the
programmer to create a Client and a Server, I just want him to create one or
the other, but not both... because creating both would end up doing twice
the same job (the Client's job).

You know what I mean?

thanks for your answers...

ThunderMusic
 
V

Vincent

I don't fully understand why you would do this. Anyway, you could do
the following:

class MyBase {
private static bool Created = false;

public override string ToString() {
return "MyBase";
}

public MyBase() {
if(Created) {
throw new Exception("I can't be created twice!");
}
Created = true;
}
}

So if this class is created, or any class that inherits it, another one
being created will show an exception.

The only problem is, if you dereference the object, the static boolean
still lingers, so you could write a Dispose method that changed Created
back to false, but the programmer would have to call it before
dereferencing the object, because Garbage Collection happens when it
wants to, and there are no guarantees when that wil happen.

Or you could just call one class "Client" and the other one
"ServerClient" which will make it obvious to the programmer that only
one is needed.

Buena Suerte!!
Vincent.
 
N

Nick Malik [Microsoft]

Singleton is an often abused pattern that should be used only to protect a
resource that requires one and only one access point (like an HTTP port or
an open file). Be careful.

Normally, if you have the need to create two alternate singletons, you have
some variation in the resource that you are trying to hide from the calling
code. I can think of two designs that will do this for you.

A) Singleton Strategy
You have a singleton object that presents a consistent interface to the
calling code. The singleton constructor, however, is used to create one or
another objects that inherit from a strategy interface. In effect, the
singleton constructor is, or calls, a strategy factory method to create a
contained object. The singleton then uses the strategy object to perform
the key varying parts of its work.

Singleton <>--------- IStrat
A
|
+------+-------+
| |
ConcStrat1 ConcStrat2


B) The singleton itself stores a child object (this is as close to what you
are trying to get at as I can figure).

This means that the base class is (a) concrete, and (b) stores a member of
its own type. Two child classes inherit from the concrete base. The base
constructor does nothing. The child constructors do nothing. You set state
on the concrete base class' other properties to help it to drive the factory
logic. When you call the concrete base class' GetReference method the first
time, it will use the other properties to decide which child object to
create and store locally. The type of the returned object is always the
base type, so you'd better not need a variation in interface for the child
objects.

Personally, I like option A better. It is cleaner and easier to maintain.

Good luck.
--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 
T

ThunderMusic

thanks a lot, I'll look into it and see if it fits the needs... I think it
will...
 
N

Nick Malik [Microsoft]

ThunderMusic said:
ok, here's the real deal... I have a Client and a Server Class and the
Server is also a Client of it's own network and does exactly all the same
things that Client does plus some other things... But I don't want the
programmer to create a Client and a Server, I just want him to create one
or the other, but not both... because creating both would end up doing
twice the same job (the Client's job).

You know what I mean?

thanks for your answers...

ThunderMusic

With all due respect, ThunderMusic, your /constraint/ may not be necessary.
Simply provide a factory method that will create the ONE object that the
client needs and be done with it. If the client is dumb enough to create
both a client and a server object, let them. Who knows... perhaps someday
the requirements will change and a new requirement will come along where the
calling code *needs* to create five clients and two servers... and your code
will break.

As long as the creation of a server object doesn't PREVENT a client object
from working, let the calling code use what they need.

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 

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