Я столкнулся с ситуацией, когда мне нужно было иметь дело с 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 Forms:
AddHandler<KeyEventHandler>(someControl,
"KeyPress",
(h) => (KeyEventHandler) h,
SomeControl_KeyPress);
, где SomeControl_KeyPress
- цель события. Ключ - лямбда-конвертер - он не работает, но убеждает компилятора, что вы дали ему действительный делегат.
(Начало 280Z28) @ Джастин: Почему бы не использовать это?
public void AddHandler<Handler>(Control c, string eventName, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, d as Delegate);
}
(конец 280Z28)