2010-01-09 3 views
1

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

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

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

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

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

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

ответ

1

Есть 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")); 
+0

Во-первых, спасибо за ваш ответ. Потрясающие!!! Подпись для 'delegateMethod' с типом возврата была надзором в сообщении. Я упростил все это и просто забыл это показать. Однако это определенно то, что мне нужно. Я уверен, что на самом деле я пытался передать целевой объект, тем не менее, на этот раз у нас все в порядке. Еще раз спасибо... – IAbstract

Смежные вопросы