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