Delegate constructor types

E

Edward Diener

The first type to a delegate constructor is obvious. It is a System::Object
* . What is the MC++ type of the second argument to the delegate constructor
? In C++ it would be a member function pointer when the first object is not
0, but I can't find its equivalent type in .NET. I would like to save an
object of that type and use that object to construct a delegate ? As an
example:

public __delegate void ADelegate();

__gc public class X
{
public:
void AMethod();
};

// Normally
X * myX = new X;
ADelegate * myADel = new ADelegate(myX,X::AMethod);
myADel(); // Calls myX::AMethod();

But let's suppose I want to save the actual method to be called, which is
the second argument to a delegate constructor. Is there a .NET type for this
? If there is, can I create an object of that type passing it a member
function ?

As an example, using the above delegate and class, let's suppose the .NET
type is called System::MemberReference and it takes a member function as a
parameter to its constructor. I could then do:

System::MemberReference * mObjMethod = new System::Method(X::AMethod);
// And then later
X * myX = new X;
ADelegate * myADel = new ADelegate(myX,mObjMethod);
myADel(); // Calls myX::AMethod();

Is this possible in some way ?

In standard C++ the concept of a member pointer exists as a pointer to a
member function of a particular class. It has the form of:

returnValue SomeClass::*SomeMethod(someParameters);

and one can say:

SomeMethod = SomeClass::AMethod;

as long as AMethod was a member function of SomeClass and had the same
signature as SomeMethod.

But I don't think I can use standard C++ when my object is a pointer to a
__gc class and my method is a member function of that __gc class.

Why would I want to do this in .NET, you say ? Because sometimes I don't
know until later what object of a certain type I want to use but I know the
member function(s) of a class of a particular signature I want to call. So
if I could create an instance of just a member function, equivalent to the
C++ member function pointer, I could pass that to another function which
will find the object, create the delegate and invoke it. I can't create the
delegate and pass that because I don't immediately know the object, but I do
know the member function(s). Finally the member function signature might be
one of a number of identical member functions of the same type for a
particular class, but the eventual code which invokes the delegate wouldn't
know or care about this. For what I want to do, C++'s ability to bind a
member function pointer to an object works better than .NET delegates which
automatically does the binding . Unfortunately I can not find out a .NET
equivalent to a C++ member function pointer in order to do this binding into
a delegate.
 
B

Bart Jacobs

You can do this as follows:

public __delegate void ADelegate();

__gc __interface IDelegateFactory {
ADelegate CreateDelegate(X *x);
};

__gc class DelegateFactoryForAMethod : public IDelegateFactory {
public:
ADelegate CreateDelegate(X *x) {
return new ADelegate(x, X::AMethod);
}
};

__gc class DelegateFactoryForBMethod : public IDelegateFactory {
public:
ADelegate CreateDelegate(X *x) {
return new ADelegate(x, X::BMethod);
}
};

IDelegateFactory *factory = new DelegateFactoryForAMethod();
// and then later
X * myX = new X;
ADelegate * myADel = factory->CreateDelegate(myX);
myADel(); // Calls myX::AMethod();

Greetings

Bart Jacobs
 
E

Edward Diener

Bart said:
You can do this as follows:

public __delegate void ADelegate();

__gc __interface IDelegateFactory {
ADelegate CreateDelegate(X *x);
};

__gc class DelegateFactoryForAMethod : public IDelegateFactory {
public:
ADelegate CreateDelegate(X *x) {
return new ADelegate(x, X::AMethod);
}
};

__gc class DelegateFactoryForBMethod : public IDelegateFactory {
public:
ADelegate CreateDelegate(X *x) {
return new ADelegate(x, X::BMethod);
}
};

IDelegateFactory *factory = new DelegateFactoryForAMethod();
// and then later
X * myX = new X;
ADelegate * myADel = factory->CreateDelegate(myX);
myADel(); // Calls myX::AMethod();

A good idea. Thanks !
 
T

Tomas Restrepo \(MVP\)

Edward,
The first type to a delegate constructor is obvious. It is a System::Object
* . What is the MC++ type of the second argument to the delegate constructor
? In C++ it would be a member function pointer when the first object is not
0, but I can't find its equivalent type in .NET. I would like to save an
object of that type and use that object to construct a delegate ?

An easier way would just be to use the CreateDelegate() static method of the
Delegate class. You can create the delegate using, for example, the object
instance and the name of the method.
 
E

Edward Diener

Tomas said:
Edward,


An easier way would just be to use the CreateDelegate() static method
of the Delegate class. You can create the delegate using, for
example, the object instance and the name of the method.

I see the CreateInstance methods. Very cool !

Is there any overhead to using reflection ? Something tells me it is a bit
slower than the way which Mr. Jacobs suggested, which I do tend to prefer. I
am just a little old-fashioned in this respect, not having used reflection
much. C++ doesn't have it and, although Python and Java do have it, I
haven't used it there before.
 
T

Tomas Restrepo \(MVP\)

Hi Edward,
I see the CreateInstance methods. Very cool !

Is there any overhead to using reflection ? Something tells me it is a bit
slower than the way which Mr. Jacobs suggested, which I do tend to prefer. I
am just a little old-fashioned in this respect, not having used reflection
much. C++ doesn't have it and, although Python and Java do have it, I
haven't used it there before.

There is certainly some overhead to using reflection, but in many cases it
might not be very significant. I'd just do some profiling to try out,
because it's a really powerful feature (and in your case, it would indeed
save you a LOT of work if you're dealing with many delegate types!)
 

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