Referencing Class Constructor with Delegate

J

Jessie

Hi,

Is it possible to reference a class constructor with a delegate?

For example:

namespace testReferenceConstructorWithDelegate
{
// if I have a delegate defined like so...
delegate myClass myClassConstructorDelegate();

// and a class like this...
class myClass
{
// with this constructor...
public myClass()
{
// (some code goes here)
}
}

// how would I go about referencing the constructor of the class
using the delegate?
class testReference
{
/*

-- this doesn't appear to work --
myClassConstructorDelegate ADelegate = myClass;

-- neither does this --
myClassConstructorDelegate ADelegate = new
myClassConstructorDelegate(myClass);

*/
}

}
 
P

Peter Duniho

Is it possible to reference a class constructor with a delegate?

I'm sure you can't by normal means. It's possible you could by
reflection. But doing so is probably not a good idea, even if you could.

Why do you want to do this? There's probably a better way to accomplish
whatever goal you're trying to achieve. If not simpler, then at least
more maintainable and less risky.

Pete
 
M

Marc Gravell

I have some .NET 3.5 code that lets you do exactly this; there are 2
use-cases I can think of:

a: factory classes, i.e. you don't know the type at compile time
(dynamic load) - and need something faster than Activator
b: generics and non-default constructors

Let me know if this would be of use...

Marc
 
J

Jessie

Why do you want to do this?

I'm trying to port some code I've written in Delphi. Without trying
to justify my implementation, what I really want is to reference an
object class with a property of another class and create instances of
that class as required.

In Delphi the syntax for declaring a class type is:

type TMyObjectClass = class of TSomeObject;

I can reference that type:

FMyObjectClass : TMyObjectClass

assign an object class to it

FMyObjectClass := TMyObjectDescendant;

and create instances of it as required

obj := FMyObjectClass.Create;

But it looks less likely that I'll be able to do that in C# so I was
trying to get there another way.

I was able to get to a point where I can do what I wanted:

Type t = Type.GetType("MyClass", true, false);
ClassConstructorInfo = t.GetConstructor(new Type[0]);
Instance = ClassConstructorInfo.Invoke(null);

Is there a better way? Is there a way that I can do what I originally
wanted with regard to referencing the class?

I appreciate your input and welcome other suggestions as I am new to
C#. I'd also be interested in hearing reasons why this approach is
risky.

Thanks!
 
J

Jessie

I have some .NET 3.5 code that lets you do exactly this ....
Let me know if this would be of use...

I'm in .NET 2.0 land but if the code still applies, then absolutely.

Thanks.
 
P

Peter Duniho

[...]
I was able to get to a point where I can do what I wanted:

Type t = Type.GetType("MyClass", true, false);
ClassConstructorInfo = t.GetConstructor(new Type[0]);
Instance = ClassConstructorInfo.Invoke(null);

Is there a better way? Is there a way that I can do what I originally
wanted with regard to referencing the class?

I appreciate your input and welcome other suggestions as I am new to
C#. I'd also be interested in hearing reasons why this approach is
risky.

It's just my opinion, but I think any time the code starts using
reflection, the code becomes more difficult to understand, and thus more
prone to breakage during maintenance. Note that I'm not talking about
some run-time risk, but rather the risk that you or someone else later
will break something because the code's behavior is less obvious due to
the reflection.

As for alternative approaches, this depends on your relationship to the
classes you're trying to instantiate. I agree with Marc regarding his
suggestions of places where this could be useful, but it sounds like for
sure the second situation doesn't apply, and possibly the first doesn't
either.

In particular, if you have some control over the types involved, then you
could provide an API on the relevant classes that does what you want in a
more clear way. For example, create a factory class that can instantiate
the instances as needed, using the Type or some other identifier to
indicate which instance to create. Or in some situations you might even
be able to make the code that needs to create the type generic, with the
constraint that the type parameter has a default constructor.

It's hard to say for sure whether these are doable in your own situation,
without knowing the full design. It's just my opinion that reflection
should be a last resort. It's pretty much the only way to do certain
things, but if there's a reasonably elegant way to do the same thing
without it, it should be avoided.

Pete
 
M

Marc Gravell

I'm in .NET 2.0 land but if the code still applies, then absolutely.

Well, it kinda demands 3.5 unfortunately. But Activator.CreateInstance
may go a long way to what you want. But I agree with Peter that such
usage should be by necessity, not habit; the new() clause goes a long
way towards this.

Marc
 
D

Dejan Stanic

Ah, nice to see another Delphi convert...

Unfortunately, there are no class ('static') /virtual/ methods or
constructors in C#. And I have yet to find the elegant way to mimic them,
although I'm coming to conclusion there isn't any. About the only way is
using the reflection, as you already discovered.

LP,
Dejan
 
J

Jessie

But I agree with Peter that such usage should be by necessity,
not habit; the new() clause goes a long way towards this.

Thanks Mark. The System.Activator class gets me what I want in a way
more clear than retrieving the constructor info.

FWIW - I'm *not* trying to do this "just because". I'm implementing
code in C# that I've written and worked with for years in Delphi.
This code uses Delphi's metaclass support to perform polymorphic
object creation. C# appears to lack metaclasses but I can get the
result I need which is the most important thing.
 
J

Jessie

Ah, nice to see another Delphi convert...

Thanx. Wish I could say I've converted by choice :-/
Unfortunately, there are no class ('static') /virtual/ methods or
constructors in C#. And I have yet to find the elegant way to mimic them,
although I'm coming to conclusion there isn't any. About the only way is
using the reflection, as you already discovered.

I found that I can do what I want by:

getting the Type of the class (in this case, a form decendant) by
either
_type = Type.GetType("MyForm", true, false);
or
_type = typeof(MyForm);

and using the System.Anctivator class to instantiate the
_instance = Activator.CreateInstance(_type);

It's not the same as Delphi's virtual "Create" constructor but it gets
the job done.
 
S

Scott Roberts

I found that I can do what I want by:
getting the Type of the class (in this case, a form decendant) by
either
_type = Type.GetType("MyForm", true, false);
or
_type = typeof(MyForm);

typeof(MyForm) is obviously "safer" than using a string literal since the
compiler will help you catch typos.
and using the System.Anctivator class to instantiate the
_instance = Activator.CreateInstance(_type);

It's not the same as Delphi's virtual "Create" constructor but it gets
the job done.

Actually, depending on your usage, Activator.CreateInstance() can be quite
slow. If you anticipate creating a lot of objects, and you expect to create
the same types of objects over and over, there are ways to improve your
performance. If you're just creating forms for a GUI, it's probably not
going to be a problem.
 

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