Reputation: 19881
I have an implementation building a delegate handler collection.
public class DelegateHandler
{
internal delegate object delegateMethod(object args);
public IntPtr PublishAsyncMethod(MethodInfo method, MethodInfo callback)
{
RuntimeMethodHandle rt;
try
{
rt = method.MethodHandle;
delegateMethod dMethod = (delegateMethod)Delegate.CreateDelegate
(typeof(delegateMethod), method.ReflectedType, method, true);
AsyncCallback callBack = (AsyncCallback)Delegate.CreateDelegate
(typeof(AsyncCallback), method.ReflectedType, callback, true);
handlers[rt.Value] = new DelegateStruct(dMethod, callBack);
return rt.Value;
}
catch (System.ArgumentException ArgEx)
{
Console.WriteLine("*****: " + ArgEx.Source);
Console.WriteLine("*****: " + ArgEx.InnerException);
Console.WriteLine("*****: " + ArgEx.Message);
}
return new IntPtr(-1);
}
}
I publish using the following:
ptr = DelegateHandler.Io.PublishAsyncMethod(
this.GetType().GetMethod("InitializeComponents"),
this.GetType().GetMethod("Components_Initialized"));
And the method I'm creating a delegate from:
public void InitializeComponents(object args)
{
// do stuff;
}
And the callback method:
public void Components_Initialized(IAsyncResult iaRes)
{
// do stuff;
}
Now, I've also already looked at this to get an idea of what I might be doing wrong. The CreateDelegate(...) is causing me to receive:
*****: mscorlib
*****:
*****: Error binding to target method.
What is wrong? The methods reside in a different, non-static public class. Any help would be greatly appreciated.
NOTE: These methods will have parameters and return values. As I understand Action
, and Action<T>
, this would not be an option.
Upvotes: 1
Views: 909
Reputation: 2549
There are 2 problems.
First, you are passing incorrect arguments to CreateDelegate
. Since you are binding to instance methods, you need to pass the instance to which the delegates will be bound, but you are passing method.ReflectedType
instead of a reference to an object of the class that declares InitializeComponents
and Components_Initialized
.
Second, the signature of InitializeComponents
does not match the declaration of delegate dMethod
. The delegate has an object
return type yet InitializeComponents
returns void
.
The following should work:
// return type changed to void to match target.
internal delegate void delegateMethod(object args);
// obj parameter added
public static void PublishAsyncMethod(object obj, MethodInfo method, MethodInfo callback)
{
delegateMethod dMethod = (delegateMethod)Delegate.CreateDelegate
(typeof(delegateMethod), obj, method, true);
AsyncCallback callBack = (AsyncCallback)Delegate.CreateDelegate
(typeof(AsyncCallback), obj, callback);
}
DelegateHandler.PublishAsyncMethod(
this, // pass this pointer needed to bind instance methods to delegates.
this.GetType().GetMethod("InitializeComponents"),
this.GetType().GetMethod("Components_Initialized"));
Upvotes: 1