Using reflection to specify the type of a delegate (to attach to an event)?

后端 未结 2 1529
陌清茗
陌清茗 2021-01-20 10:40

What I effectively want to do is something like this (I realise this is not valid code):

// Attach the event.
try
{
    EventInfo e = mappings[name];
    (e.         


        
相关标签:
2条回答
  • 2021-01-20 11:10

    You can use Delegate.CreateDelegate to accomplish your goal like this:

    public void RegisterHandler(string name)
    {
        EventInfo e = mappings[name];
        EventHandler<AutoWrapEventArgs> handler = (s, raw) =>
            {
                func.Call(this, raw.GetParameters());
            };
        e.AddEventHandler(this, Delegate.CreateDelegate(e.EventHandlerType, null, handler.Method));
    }
    
    0 讨论(0)
  • 2021-01-20 11:15

    Bingo! The trick is to get a reference to the constructor for the delegate type and then invoke it using the following parameters:

    • The target object of the delegate (backend.Target)
    • The delegate's pointer (backend.Method.MethodHandle.GetFunctionPointer())

    The actual code that does this looks like (t in this case is the generic argument provided to EventHandler<> during inheritance):

    Type t = e.EventHandler.GetGenericArguments()[0];
    Delegate handler = (Delegate)
        typeof(EventHandler<>)
        .MakeGenericType(t)
        .GetConstructors()[0]
        .Invoke(new object[]
            {
                backend.Target,
                backend.Method.MethodHandle.GetFunctionPointer()
            });
    

    You can then use the delegate for the event adding like so:

    e.AddEventHandler(this, handler);
    
    0 讨论(0)
提交回复
热议问题