PC Review


Reply
Thread Tools Rate Thread

How to allow instanciation of a class from another class method inside the same assembly???

 
 
Bob Rock
Guest
Posts: n/a
 
      13th May 2004
Hello,

I'd like to be able to allow instanciation of a class (class Class_A) only
from another class method (class Class_B). And I'd like to write the
necessary code to enforce this behavior even inside the same assembly where
class Class_A and Class_B are defined.
I've written the code that does this BUT I'd like to understand if this is
the most correct way to obtain such a result.

This is my simplified code:

// abstract class
public abstract class Class_C
{
public abstract void Method_1();
}

public class Class_B
{
// method that returns instances of class Class_A
public Class_A Method_2()
{
return new Class_A();
}

// nested private class - implements the abstract class Class_C
private class Class_A : Class_C
{
public override void Method_1
{
// implementation code
}
}
}

The above implentation allows the writing of the following "client" code:

Class_B b = new Class_B();
Class_C c = b.Method_2(); // creating an instance of class Class_A
c.Method_1(); // calling Method_1() of class Class_A

This code works well, the only thing I don't like is that Class_A is
completely unknown by code outside class Class_B.
Instead of an abstract class I could have used an interface but, since I
won't need to implement that interface more than once, I thought using an
abstract class to hold a reference to an instance of class Class_A to be
more correct.

Can anyone review this approach and tell me if there is any better solution?


Bob Rock








 
Reply With Quote
 
 
 
 
Morten Wennevik
Guest
Posts: n/a
 
      13th May 2004
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.

public class Class_A
{
private Class_A()
{
}

public void Method_1()
{
}

public static Class_A Method_2()
{
return new Class_A();
}

}



Happy coding!
Morten Wennevik [C# MVP]
 
Reply With Quote
 
Bob Rock
Guest
Posts: n/a
 
      13th May 2004
> 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.
>
> public class Class_A
> {
> private Class_A()
> {
> }
>
> public void Method_1()
> {
> }
>
> public static Class_A Method_2()
> {
> return new Class_A();
> }
>
> }
>
>
> 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



 
Reply With Quote
 
Mark Broadbent
Guest
Posts: n/a
 
      13th May 2004
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();
}
}
}

--

Br,
Mark Broadbent
mcdba , mcse+i
=============
"Bob Rock" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> > 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.
> >
> > public class Class_A
> > {
> > private Class_A()
> > {
> > }
> >
> > public void Method_1()
> > {
> > }
> >
> > public static Class_A Method_2()
> > {
> > return new Class_A();
> > }
> >
> > }
> >
> >
> > 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
>
>
>



 
Reply With Quote
 
Bob Rock
Guest
Posts: n/a
 
      13th May 2004
> 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


 
Reply With Quote
 
Mark Broadbent
Guest
Posts: n/a
 
      13th May 2004
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();
}
}
}

--

--

Br,
Mark Broadbent
mcdba , mcse+i
=============
"Bob Rock" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> > 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.
> >
> > public class Class_A
> > {
> > private Class_A()
> > {
> > }
> >
> > public void Method_1()
> > {
> > }
> >
> > public static Class_A Method_2()
> > {
> > return new Class_A();
> > }
> >
> > }
> >
> >
> > 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
>
>
>



 
Reply With Quote
 
Bob Rock
Guest
Posts: n/a
 
      13th May 2004
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




 
Reply With Quote
 
Mark Broadbent
Guest
Posts: n/a
 
      13th May 2004
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?

--

--

Br,
Mark Broadbent
mcdba , mcse+i
=============
"Bob Rock" <(E-Mail Removed)> wrote in message
news:%(E-Mail Removed)...
> > 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
>
>



 
Reply With Quote
 
Bob Rock
Guest
Posts: n/a
 
      13th May 2004
> 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.


Clear. A protected constructor would do the job.

Bob Rock


 
Reply With Quote
 
Mark Broadbent
Guest
Posts: n/a
 
      13th May 2004
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.

--

--

Br,
Mark Broadbent
mcdba , mcse+i
=============
"Bob Rock" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> 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
>
>
>
>



 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Retrieving from inside a static method the type of the containing class??? Bob Rock Microsoft C# .NET 8 29th Dec 2006 09:01 PM
call a mnuFileNew_Click method from a Main MDI class from another class (can be a MdiChild class.. )? M. G, Microsoft Dot NET Framework Forms 1 31st May 2006 06:28 AM
calling an assembly from inside a class TJS Microsoft ASP .NET 4 1st Oct 2004 06:43 PM
How to allow instanciation of a class from another class method inside the same assembly??? Bob Rock Microsoft Dot NET Framework 13 13th May 2004 03:58 PM
How to allow instanciation of a class from another class method inside the same assembly??? Bob Rock Microsoft C# .NET 11 13th May 2004 03:58 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 07:06 AM.