使用反射来指定一个委托类型(附加到一个事件)? [英] Using reflection to specify the type of a delegate (to attach to an event)?

查看:128
本文介绍了使用反射来指定一个委托类型(附加到一个事件)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有效地想要做的就是这样的事情(我知道这是不是有效的code):

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.EventHandlerType) handler = (sender, raw) =>
    {
        AutoWrapEventArgs args = raw as AutoWrapEventArgs;
        func.Call(this, args.GetParameters());
    };

    e.AddEventHandler(this, handler);
}
...

现在我知道e.EventHandlerType永远导出从事件处理程序< AutoWrapEventArgs取代。但是,我不能只是做:

Now I know that the e.EventHandlerType will always derive from EventHandler<AutoWrapEventArgs>. However, I can't just do:

    EventHandler<AutoWrapEventArgs> handler = (sender, raw) =>
    {
        AutoWrapEventArgs args = raw as AutoWrapEventArgs;
        func.Call(this, args.GetParameters());
    };

    e.AddEventHandler(this, handler);

由于.NET抱怨,有适用于从事件处理程序和LT无需转换; AutoWrapEventArgs&GT;到事件处理程序&LT; D​​ataEventArgs&GT;当的addEventHandler被调用。这是确切的消息:

As .NET complains that there is no conversion applicable from EventHandler<AutoWrapEventArgs> to EventHandler<DataEventArgs> when AddEventHandler is called. This is the exact message:

Object of type 'System.EventHandler`1[IronJS.AutoWrapObject+AutoWrapEventArgs]'
cannot be converted to type
'System.EventHandler`1[Node.net.Modules.Streams.NodeStream+DataEventArgs]'.

我也尝试过使用调用动态使用e.EventHandlerType的构造,但没有办法通过委托定义来调用()的参数列表(因为没有从委托转换为对象)。

I have also tried using Invoke to dynamically use the constructor of e.EventHandlerType, but there's no way to pass the delegate definition to Invoke()'s parameter list (because there is no conversion from delegate to object).

有没有一种方法,我可以使用反射来解决这个问题呢?

Is there a way I can use reflection to get around this problem?

推荐答案

宾果!关键是要获得委托类型的引用,构造函数,然后使用下面的参数来调用它:

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

  • 委托的目标对象(backend.Target)
  • 委托的指针(backend.Method.MethodHandle.GetFunctionPointer())

实际的code,这是否看起来像(T在这种情况下,是提供给事件处理程序和LT通用的说法;>继承时):

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

这篇关于使用反射来指定一个委托类型(附加到一个事件)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆