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:
elegate* 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;
}