I delegate vengono usati diffusamente per la gestione degli eventi, cioè quando voglio fare in modo che una classe fornisca delle notifiche ai suoi utilizzatori.
L’azione può essere causata dall’utente, ad esempio il clic su un pulsante oppure può essere generata da un altro programma logico, ad esempio modificare le proprietà di un valore.
La classe che invia (o genera) l’evento è chiamata event sender e le classi che ricevono (o gestiscono) l’evento sono chiamate subscribers.
Il mittente dell’evento non sa quale oggetto o metodo riceverà (dovrà gestire) gli eventi generati.
1.1 Come usare gli eventi
Ora, conosciamo i delegate come dei puntatori a funzione identificati univocamente dalla loro firma.
Pensiamo allo scopo degli eventi: vogliamo che un particolare codice venga eseguito quando accade qualcosa da qualche parte nel mio sistema.
Per fare questo, creiamo dei metodi specifici per il codice che vogliamo che venga eseguito.
Il collante tra l’evento e il metodo sono i delegati: l’evento deve internamente memorizzare una lista di puntatori a funzioni da eseguire quando tale evento viene lanciato (aggiunti tramite il comando +=).
Ovviamente se vogliamo chiamare un metodo, dobbiamo sapere quali parametri passare a quest’ultimo!
Consideriamo i delegate quindi come dei “contract” tra l’evento e i metodi che vengono chiamati.
Quando dichiaro un evento con la parola chiave event, devo indicare come tipo un delegate, quindi la firma del metodo che deve essere chiamato al lancio dell’evento.
2.La parola chiave event
Per definire un evento, utilizzare event nella firma del metodo che genera l’evento e specificare il tipo di delegato questo ultimo.
In genere, per generare un evento, si aggiunge un metodo contrassegnato come protected e virtual chiamandolo OnEventName.
Il seguente esempio mostra come dichiarare un evento denominato ThresholdReached: l’evento viene associato al delegato con il EventHandler e viene generato in un metodo denominato OnThresholdReached.
3. Utilizzare i delegate del .NET
Negli esempi precedenti non abiamo posto particolare attenzione sulla firma che deve avere il delegate; .NET consiglia di seguire però questo standard per la definizione dei delegate:
quindi quando sollevo l’evento devo obbligatoriamente fornisce la classe che l’ha sollevato e degli argomenti di evento.
Il .NET fornisce un delegate apposito, chiamato EventHandler.
Il secondo argomento è un’istanza della classe EventArgs, si tratta di un tipo che non contiene aluna informazione ma la cui adozione è congliata per un requisito di forma che vedremo fra poco.
Il modo più semplice di valorizzarlo è tramite il suo campo statico Empty:
Qualora volessimo fornire all’evento ulteriori informazioni di stato, conviene creare una classe personalizzata che derivi da EventArgs il cui nome convenzionalmente termina con tale suffisso.
4. Esempio
Un esempio di gestione degli eventi è la classe CameraWatchDog di IMACore, che andiamo ad analizzare.