> Hi Bob,
>
> Well, your code does not compile :P (or at least did not for me). Something about the return type being less accessible than the method.
However, changing the return type for Method_1 to Class_C will do the trick,
but I suspect you did so already.
> There is another approach of controlled instantiation which only involves one class.
>
[quoted text clipped - 17 lines]
> Happy coding!
> Morten Wennevik [C# MVP]
Morten,
I'm sorry, I had to clean up my code to make the post and made a mistake.
Method_1 indeed returns an instance of Class_C.
Morten thank you for your code but it is not what I was asking for.
I'd like a class method (class Class_B method) to be the only one able to
return instances of a ANOTHER class (class Class_A).
Bob Rock
Mark Broadbent - 13 May 2004 14:08 GMT
As Morton has shown you, you can prevent a class from being instanciated
from outside its type by making it's constructer private to its' class. That
is essentially what you want. Remember that your class C needs to be public
in order to assign that type to the reference pointer. I know you want one
class to be the ONLY ONE to be able to return objects of another type but
from what I see there are 2 problems to this.
1. To force a type to be inherited you would make it abstract, but by making
it abstract you cannot instanciate objects of its type (which you need to
do)
2. By hiding the constructor from outside the type you are preventing the
class from being inherited, which prevents you from returning an object of
its type from outside its class using the base object
Morton way to have a type become it's own object factory is the best way to
do what you what (as far as I can figure out). Please see code.
using System;
namespace ConsoleApplication1
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class ClassC
{
public void SayHello()
{
Console.WriteLine("Hello");
}
private ClassC()
{
//constructor is only visible within its own type
}
public static ClassC ReturnC()
{
return new ClassC();
}
}
public class AppStart
{
[STAThread]
static void Main(string[] args)
{
//ClassC c = new ClassC(); //would fail
//c.SayHello();
ClassC c = ClassC.ReturnC();
c.SayHello();
}
}
}

Signature
Br,
Mark Broadbent
mcdba , mcse+i
=============
> > Hi Bob,
> >
[quoted text clipped - 36 lines]
>
> Bob Rock
Bob Rock - 13 May 2004 14:37 GMT
> 2. By hiding the constructor from outside the type you are preventing the
> class from being inherited, which prevents you from returning an object of
> its type from outside its class using the base object
This point is not exactly clear to me.
Bob Rock
Mark Broadbent - 13 May 2004 15:20 GMT
Ill try to explain better.
Imagine that we got ClassC and we have found a way to stop it being
constructed outside of ClassC *except* we need to find a way to allow ClassB
to instanciate it. My thoughts were that we could create a public (non
static) method (within ClassC) that returns an object instance of type C.
Obviously the method is non static and so it can only be called through an
instance of ClassC (which we have just said cannot be done on its own)
HOWEVER I thought why not inherit ClassC into ClassB allowing us to call
the method (and return a type instance) through base.MethodName().
Unfortunately since the ClassC constructor is private, that in itself
prevents the class being inherited, and therefore the pack of cards comes
falling down again.
Hope I made more sense that time?

Signature
--
Br,
Mark Broadbent
mcdba , mcse+i
=============
> > 2. By hiding the constructor from outside the type you are preventing the
> > class from being inherited, which prevents you from returning an object of
[quoted text clipped - 3 lines]
>
> Bob Rock
Bob Rock - 13 May 2004 15:25 GMT
> Imagine that we got ClassC and we have found a way to stop it being
> constructed outside of ClassC *except* we need to find a way to allow ClassB
[quoted text clipped - 7 lines]
> prevents the class being inherited, and therefore the pack of cards comes
> falling down again.
Clear. A protected constructor would do the job.
Bob Rock
Mark Broadbent - 13 May 2004 14:39 GMT
Bob, another avenue that you could take for this kind of behaviour is to
only allow the instanciation of ClassC if and only if an instance of ClassA
is passed to it. You could then do validaty checking on the ClassA object if
necessary.
e.g.
using System;
namespace ConsoleApplication1
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class ClassC
{
public void SayHello()
{
Console.WriteLine("Hello");
}
public ClassC(ClassB key)
{
//constructor must have instance of ClassB passed to it otherwise compile
time error will occur
//in order to return error at run time instead you could Add back a
public ClassC() constructor
//and throw an exception in it.
}
}
public class ClassB
{
//any implementation you require
}
public class AppStart
{
[STAThread]
static void Main(string[] args)
{
//ClassC c = new ClassC(); //would fail
//c.SayHello();
ClassC c = new ClassC(new ClassB());
c.SayHello();
Console.ReadLine();
}
}
}

Signature
--
Br,
Mark Broadbent
mcdba , mcse+i
=============
> > Hi Bob,
> >
[quoted text clipped - 36 lines]
>
> Bob Rock
Bob Rock - 13 May 2004 15:04 GMT
Mark, thank you for your effort.
Anyhow I identifies another possible solution that removes the "problem" of
the abstract class.
// -- the managed class
public class ManagedClass
{
// -- non public constructor
protected ManagedClass()
{
}
}
// -- the manager class
public class ManagerClass
{
// -- method returning an instance of managed class
public ManagedClass CreateInstance()
{
return new PrivateManagedClass();
}
// -- nested class
private PrivateManagedClass : ManagedClass
{
public PrivateManagedClass() : base()
{
}
}
}
Why not have ManagerClass directly inherit from ManagedClass? Because I
don't want to expose ManagedClass methods on ManagerClass.
Bob Rock
Mark Broadbent - 13 May 2004 15:35 GMT
yes well done! a protected constructor gets around this issue. The only
potential problem I can see with all this, is that if the ManagedClass has
public members, then they will be accessible through the ManagerClass
instance (because they will be inherited).
Anyway you seem to have got where you wanted so I'll sign off for now.
bye.

Signature
--
Br,
Mark Broadbent
mcdba , mcse+i
=============
> Mark, thank you for your effort.
> Anyhow I identifies another possible solution that removes the "problem" of
[quoted text clipped - 33 lines]
>
> Bob Rock
Bob Rock - 13 May 2004 15:51 GMT
> yes well done! a protected constructor gets around this issue. The only
> potential problem I can see with all this, is that if the ManagedClass has
> public members, then they will be accessible through the ManagerClass
> instance (because they will be inherited).
> Anyway you seem to have got where you wanted so I'll sign off for now.
Mark there is no such issue.
The manager class DOES NOT inherit from the managed class, the private
nested class inside the manager class is inheriting.
Bob Rock
Mark Broadbent - 13 May 2004 15:58 GMT
sorry yes, didnt look at your code listing long enough, was still playing
with my code!
Anyway well done.

Signature
--
Br,
Mark Broadbent
mcdba , mcse+i
=============
> > yes well done! a protected constructor gets around this issue. The only
> > potential problem I can see with all this, is that if the ManagedClass has
[quoted text clipped - 7 lines]
>
> Bob Rock