Создание коллекции обработчиков делегатов - PullRequest
1 голос
/ 09 января 2010

У меня есть реализация, создающая коллекцию обработчиков делегатов.

   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);
            }
   }

Я публикую, используя следующее:

 ptr = DelegateHandler.Io.PublishAsyncMethod(
    this.GetType().GetMethod("InitializeComponents"),
    this.GetType().GetMethod("Components_Initialized"));

И метод, из которого я создаю делегата:

    public void InitializeComponents(object args)
    { 
           // do stuff;
    }

И метод обратного вызова:

public void Components_Initialized(IAsyncResult iaRes)
{
       // do stuff;
}

Теперь я также уже посмотрел на этот , чтобы понять, что я могу делать неправильно. CreateDelegate (...) заставляет меня получать:

*****: mscorlib
*****: 
*****: Error binding to target method.

Что не так? Методы находятся в другом нестатическом публичном классе. Любая помощь будет принята с благодарностью.

ПРИМЕЧАНИЕ. Эти методы будут иметь параметры и возвращаемые значения. Как я понимаю Action и Action<T>, это не вариант.

1 Ответ

1 голос
/ 09 января 2010

Есть 2 проблемы.

Сначала вы передаете неверные аргументы CreateDelegate. Поскольку вы привязываетесь к методам экземпляра, вам нужно передать экземпляр, к которому будут привязаны делегаты, но вы передаете method.ReflectedType вместо ссылки на объект класса, который объявляет InitializeComponents и Components_Initialized.

Во-вторых, подпись InitializeComponents не соответствует объявлению делегата dMethod. Делегат имеет тип возврата object, но InitializeComponents возвращает void.

Должно работать следующее:

// 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"));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...