Me encontré con una situación en la que necesitaba lidiar con una Delegaterestricció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 Handleren 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. converttoma un Handlerargumento 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 KeyPressevento en un control de Windows Forms:
AddHandler<KeyEventHandler>(someControl,
"KeyPress",
(h) => (KeyEventHandler) h,
SomeControl_KeyPress);
¿Dónde SomeControl_KeyPressestá 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)