我遇到了一种情况,我需要在Delegate
内部处理一个但我想要一个通用约束。具体来说,我想使用反射添加一个事件处理程序,但我想为委托使用一个通用参数。下面的代码不起作用,因为“处理程序”是一个类型变量,编译器不会Handler
转换为Delegate
:
public void AddHandler<Handler>(Control c, string eventName, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, (Delegate) d);
}
但是,您可以传递一个为您进行转换的函数。convert
接受一个Handler
参数并返回一个Delegate
:
public void AddHandler<Handler>(Control c, string eventName,
Func<Delegate, Handler> convert, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, convert(d));
}
现在编译器很高兴。调用该方法很容易。例如,附加到KeyPress
Windows 窗体控件上的事件:
AddHandler<KeyEventHandler>(someControl,
"KeyPress",
(h) => (KeyEventHandler) h,
SomeControl_KeyPress);
SomeControl_KeyPress
事件目标在哪里。关键是转换器 lambda - 它不起作用,但它让编译器相信你给了它一个有效的委托。
(从 280Z28 开始)@Justin:为什么不使用这个?
public void AddHandler<Handler>(Control c, string eventName, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, d as Delegate);
}
(完 280Z28)