I came across a situation where I needed to deal with a Delegate
internally but I wanted a generic constraint. Specifically, I wanted to add an event handler using reflection, but I wanted to use a generic argument for the delegate. The code below does NOT work, since "Handler" is a type variable, and the compiler won't cast Handler
to Delegate
:
public void AddHandler<Handler>(Control c, string eventName, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, (Delegate) d);
}
However, you can pass a function that does the conversion for you. convert
takes a Handler
argument and returns a Delegate
:
public void AddHandler<Handler>(Control c, string eventName,
Func<Delegate, Handler> convert, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, convert(d));
}
Now the compiler is happy. Calling the method is easy. For example, attaching to the KeyPress
event on a Windows Forms control:
AddHandler<KeyEventHandler>(someControl,
"KeyPress",
(h) => (KeyEventHandler) h,
SomeControl_KeyPress);
where SomeControl_KeyPress
is the event target. The key is the converter lambda - it does no work, but it convinces the compiler you gave it a valid delegate.
(Begin 280Z28) @Justin: Why not use this?
public void AddHandler<Handler>(Control c, string eventName, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, d as Delegate);
}
(End 280Z28)