Me encontré con una situación en la que necesitaba lidiar con una Delegate
restricción interna pero quería una restricción genérica. Específicamente, quería agregar un controlador de eventos usando la reflexión, pero quería usar un argumento genérico para el delegado. El siguiente código NO funciona, ya que "Handler" es una variable de tipo y el compilador no se convierte Handler
en Delegate
:
public void AddHandler<Handler>(Control c, string eventName, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, (Delegate) d);
}
Sin embargo, puede pasar una función que realice la conversión por usted. convert
toma un Handler
argumento y devuelve un Delegate
:
public void AddHandler<Handler>(Control c, string eventName,
Func<Delegate, Handler> convert, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, convert(d));
}
Ahora el compilador está contento. Llamar al método es fácil. Por ejemplo, adjuntar al KeyPress
evento en un control de Windows Forms:
AddHandler<KeyEventHandler>(someControl,
"KeyPress",
(h) => (KeyEventHandler) h,
SomeControl_KeyPress);
¿Dónde SomeControl_KeyPress
está el objetivo del evento? La clave es el convertidor lambda: no funciona, pero convence al compilador de que le dio un delegado válido.
(Comienza 280Z28) @Justin: ¿Por qué no usar esto?
public void AddHandler<Handler>(Control c, string eventName, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, d as Delegate);
}
(Fin 280Z28)