Я зіткнувся з ситуацією, коли мені потрібно було мати справу з 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) @Justin: Чому б не використовувати це?
public void AddHandler<Handler>(Control c, string eventName, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, d as Delegate);
}
(Кінець 280Z28)