Ich stieß auf eine Situation, in der ich mich Delegateintern mit einem Problem befassen musste, aber ich wollte eine generische Einschränkung. Insbesondere wollte ich einen Ereignishandler mithilfe von Reflection hinzufügen, aber ich wollte ein generisches Argument für den Delegaten verwenden. Der folgende Code funktioniert NICHT, da "Handler" eine Typvariable ist und der Compiler nicht Handlerin Folgendes umwandelt Delegate:
public void AddHandler<Handler>(Control c, string eventName, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, (Delegate) d);
}
Sie können jedoch eine Funktion übergeben, die die Konvertierung für Sie durchführt. convertnimmt ein HandlerArgument und gibt ein Delegate:
public void AddHandler<Handler>(Control c, string eventName,
Func<Delegate, Handler> convert, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, convert(d));
}
Jetzt ist der Compiler glücklich. Das Aufrufen der Methode ist einfach. Beispiel: Anhängen an das KeyPressEreignis in einem Windows Forms-Steuerelement:
AddHandler<KeyEventHandler>(someControl,
"KeyPress",
(h) => (KeyEventHandler) h,
SomeControl_KeyPress);
Wo SomeControl_KeyPressist das Ereignisziel? Der Schlüssel ist der Konverter Lambda - er funktioniert nicht, überzeugt aber den Compiler, den Sie ihm als gültigen Delegaten gegeben haben.
(Beginnen Sie mit 280Z28) @Justin: Warum nicht?
public void AddHandler<Handler>(Control c, string eventName, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, d as Delegate);
}
(Ende 280Z28)