代码之家  ›  专栏  ›  技术社区  ›  BrunoLM

如何动态订阅事件?

  •  2
  • BrunoLM  · 技术社区  · 14 年前


    我需要检测事件何时触发。为了做到这一点,我试图订阅动态的事件。

    in here here 期望 object sender, EventArgs e

    public delegate void OnEventA(int id);
    public delegate void OnEventB(double num, string name);
    

    如何创建正确的代理?

    2 回复  |  直到 7 年前
        1
  •  6
  •   Tomas Petricek    14 年前

    EventInfo AddEventHandler 你可以用的。如果没有委托实例,那么可以使用 Delegate.CreateDelegate :

    var eh = Delegate.CreateDelegate(ei.EventHandlerType, target, methodInfo);
    ei.AddEventHandler(owner, eh);
    

    在这个例子中 target 是委托的目标对象,并且 methodInfo MethodInfo 对象。最后, owner 事件发生的对象 ei 属于。

        2
  •  3
  •   Community kfsone    7 年前

    经过研究,我发现了一些文章:

    它帮助我明白我想做什么,我应该做什么。

    Delegate.CreateDelegate 通过 EventHandlerType

    Delegate handler = Delegate.CreateDelegate(evt.EventHandlerType, abc, mi1, false);
    evt.AddEventHandler(target, handler);
    

    进一步的挖掘使我找到了这个方法。我可以使用lambda表达式订阅事件。使用 Action<T> 我可以订阅不同类型和数量的参数。

    public static Delegate Create<T>(EventInfo e, Action<T> a)
    {
        var parameters = e.EventHandlerType.GetMethod("Invoke").GetParameters().Select(p => Expression.Parameter(p.ParameterType, "p")).ToArray();
        var exp = Expression.Call(Expression.Constant(a), a.GetType().GetMethod("Invoke"), parameters);
        var l = Expression.Lambda(exp, parameters);
        return Delegate.CreateDelegate(e.EventHandlerType, l.Compile(), "Invoke", false);
    }
    

    e.AddEventHandler(this, EventManager.Create<int>(e, (x) => Console.WriteLine("Execute")));