相关
我需要检测何时触发事件。为此,我试图动态订阅事件。
问题是我有不同类型的委托,并非所有事件都有相同的签名。提供的解决方案in here和here期望object sender, EventArgs e
,我没有使用,所以我得到一个异常,告诉类型不匹配。
以下是我所拥有的代表的一些例子:
public delegate void OnEventA(int id);
public delegate void OnEventB(double num, string name);
如何创建正确的委托?
答案 0 :(得分:6)
EventInfo
有一个可以使用的方法AddEventHandler
。如果您没有委托实例,则可以使用Delegate.CreateDelegate
动态创建委托:
var eh = Delegate.CreateDelegate(ei.EventHandlerType, target, methodInfo);
ei.AddEventHandler(owner, eh);
在此示例中,target
是委托的目标对象,methodInfo
是MethodInfo
对象中方法的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")));