Natknąłem się na sytuację, w której musiałem poradzić sobie Delegate
wewnętrznie, ale chciałem mieć ogólne ograniczenie. W szczególności chciałem dodać procedurę obsługi zdarzeń za pomocą odbicia, ale chciałem użyć ogólnego argumentu dla delegata. Poniższy kod NIE działa, ponieważ „Handler” jest zmienną typu, a kompilator nie będzie rzutował Handler
na Delegate
:
public void AddHandler<Handler>(Control c, string eventName, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, (Delegate) d);
}
Możesz jednak przekazać funkcję, która dokona konwersji za Ciebie. convert
przyjmuje Handler
argument i zwraca Delegate
:
public void AddHandler<Handler>(Control c, string eventName,
Func<Delegate, Handler> convert, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, convert(d));
}
Teraz kompilator jest szczęśliwy. Wywołanie metody jest łatwe. Na przykład dołączanie do KeyPress
zdarzenia w kontrolce Windows Forms:
AddHandler<KeyEventHandler>(someControl,
"KeyPress",
(h) => (KeyEventHandler) h,
SomeControl_KeyPress);
gdzie SomeControl_KeyPress
jest cel zdarzenia. Kluczem jest lambda konwertera - nie działa, ale przekonuje kompilator, któremu nadałeś mu prawidłowego delegata.
(Rozpocznij 280Z28) @Justin: Dlaczego nie użyć tego?
public void AddHandler<Handler>(Control c, string eventName, Handler d) {
c.GetType().GetEvent(eventName).AddEventHandler(c, d as Delegate);
}
(Koniec 280Z28)