Checking which method a delegate points to

  • Thread starter Thread starter Russell Hind
  • Start date Start date
R

Russell Hind

I have a delegate which I use to store a current 'state' function (for a
statemachine inside a form).

__delegate void State_t(const Message_c& Message);

I assign to it such as

m_State = new State_t(this, StateShutdown);

How can I later check which method the State is pointing to? And is
there an easier way to change the method when needed, rather than
creating a whole new State_t object (when the object pointer doesn't
change?)

Thanks

Russell
 
Russell Hind said:
I have a delegate which I use to store a current 'state' function (for a
statemachine inside a form).

A single delegate may point to multiple functions, so you have to compare the
complete delegate list returned by the delegate member method
GetInvokationList.

I have 2 solutions (surely there are more and perhaps better ones):

a)

Iterate through the array returned by
delegatePointer->GetInvokationList() and compare the delegates with a stored
instance (only for comparison) of a delegate pointing only to the function you
want to check.

b)

Use reflection - i´ve attached a sample code below for illustration only.
I haven´t checked which method is faster, but i suppose solution a) is
faster.

Surely a native pointer comparison would be much faster, but
that would require the objects to be pinned
(temporarily or even worse permanently), so that they may not
be moved around. So i wouldn´t recommend that to do.

Hope that and the code below helps - a bit.
Andre

PS: I don´t know if the my solution(s) are the best way to accomplish
a safe and fast comparison of delegates - if anybody
knows a better it would be nice if it would be posted
in this thread - thank you in advance


//
// Code isn´t optimized should be used/handled only
// as an illustrative sample

#using <mscorlib.dll>

using namespace System;

//
// Class1
//
// Implements sample delegates used for comparison in the main method

__gc class Class1
{
public:

__delegate void FunctionPrototype();

void Fun1() {}
void Fun2() {}
};

int _tmain()
{
//
// Create multiple delegates for comparison

Class1* o1 = new Class1();
Class1* o2 = new Class1();
Class1::FunctionPrototype* f1 = new Class1::FunctionPrototype(o1, Class1::Fun1);
Class1::FunctionPrototype* f2 = new Class1::FunctionPrototype(o1, Class1::Fun2);
Class1::FunctionPrototype* f3 = new Class1::FunctionPrototype(o1, Class1::Fun1);
f1+= new Class1::FunctionPrototype(o1, Class1::Fun2); // Let the delegate point to Fun1 and Fun2


//
// Saved copy for comparison

Class1::FunctionPrototype* comparisonDelegate =
new Class1::FunctionPrototype(o1, Class1::Fun1);


System::Delegate* delegateList[] = f1->GetInvocationList();
unsigned int delegateCount = delegateList->Count;

//
// Compare delegates directly

for (unsigned int i = 0; i < delegateCount; ++i)
{
bool isSame = delegateList->Equals(comparisonDelegate);
Console::WriteLine(S"Is same delegate: {0}", isSame.ToString());
}

//
// Compare delegates by using reflection - should be slower than directly
// comparing delegates

for (unsigned int i = 0; i < delegateCount; ++i)
{
//
// The delegate is equal if the following 2 comparisons
// return true

Console::WriteLine(S"Delegate points to the same target object: {0}",
(delegateList->Target == o1).ToString());

// May throw an exception if Fun1 is an overloaded function
Console::WriteLine(S"Delegate points to the same function: {0}",
(delegateList->Method ==
o1->GetType()->GetMethod(S"Fun1")).ToString());
}


return 0;
}
 
Back
Top