Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / May 2004

Tip: Looking for answers? Try searching our database.

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

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Bob Rock - 13 May 2004 10:57 GMT
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
Morten Wennevik - 13 May 2004 11:24 GMT
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]
Bob Rock - 13 May 2004 11:36 GMT
> 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

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.