如何动态订阅活动?

时间:2010-09-22 17:34:07

标签: c# .net reflection

相关


我需要检测何时触发事件。为此,我试图动态订阅事件。

问题是我有不同类型的委托,并非所有事件都有相同的签名。提供的解决方案in herehere期望object sender, EventArgs e,我没有使用,所以我得到一个异常,告诉类型不匹配。

以下是我所拥有的代表的一些例子:

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

如何创建正确的委托?

2 个答案:

答案 0 :(得分:6)

EventInfo有一个可以使用的方法AddEventHandler。如果您没有委托实例,则可以使用Delegate.CreateDelegate动态创建委托:

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

在此示例中,target是委托的目标对象,methodInfoMethodInfo对象中方法的target。最后,owner是事件ei所属的对象。

答案 1 :(得分:2)

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

它帮助我理解了我想要做的事情,我应该这样做。

我需要使用Delegate.CreateDelegate传递EventHandlerType(事件的类型,委托),类的实例和方法的方法信息(来自上一个参数中的类) )将处理该事件。 Target是触发此事件的控件。

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是EventInfo; EventManager是上面带有静态方法的类)

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