In questa lezione del corso sul linguaggio C#, prenderemo in considerazione un argomento molto complicato, a mio modo di vedere, che consente alle applicazioni di gestire gli eventi, si tratta dei delegati. In applicazioni visuali, tramite il Visual Studio è semplice gestire gli eventi, perché è tutto automatico, ma per meglio capire il funzionamento proviamo a spiegare nel più semplice modo possibile i delegati e gli eventi. I delegati esistono indipendentemente dagli eventi ( pressione di un tasto, scelta di un valore da una lista, ecc.. ecc..) e sebbene i due concetti siano strettamente legati, è possibile utilizzare i delegati semplicemente per disaccoppiare il codice applicativo, demandando funzionalità specifiche all’esterno di una determinata classe. Si può pensare ai delegati come ad una versione più fine delle interfacce, infatti è possibile implementare anche solo un metodo alla volta e sono dei veri e propri oggetti che incapsulano uno specifico metodo finalizzato a rispondere ad una funzione specifica e circoscritta.
I delegati sono dichiarati tramite la parola chiave delegate e come dice la parola stessa vengono delegati per altri metodi, che possono appartenere a più classi, sono simili ai puntatori a funzione del C++, anche se indipendenti dai tipi e sono protetti. Vediamo questo esempio nel quale una funzione viene delegata:
using System; namespace BaseApp { public delegate double Delegato(double dVal); class Program { static void Main(string[] args) { Program pr = new Program(); Delegato q = new Delegato(pr.Quadrato); double dVal = 2.5; dVal = q(dVal); Console.WriteLine("Il valore è {0}", dVal); Console.ReadKey(); } public double Quadrato(double dVal) { return dVal * dVal; } } }
come si vede da questo semplice esempio, il metodo Quadrato della classe Program viene delegato con il nome Delegato. Una peculiarità dei delegati è che possono essere sommati o sotratti, vediamone un esempio:
using System; namespace BaseApp { public delegate double Delegato(double dVal); class Program { static void Main(string[] args) { Program pr = new Program(); Delegato q = new Delegato(pr.Quadrato); q += new Delegato(pr.Cubo); double dVal = 2.5; dVal = q(dVal); Console.WriteLine("\n\nDelego il Quadrato \ ed il Cubo con una somma"); Console.ReadKey(); } public double Quadrato(double dVal) { Console.WriteLine("Il valore del \ prodotto tra {0} e {0} è {1}", dVal, dVal * dVal); return dVal * dVal; } public double Cubo(double dVal) { Console.WriteLine("Il valore del prodotto tra \ {0} e {0} e {0} è {1}", dVal, dVal * dVal * dVal); return dVal * dVal * dVal; } } }
come si può vedere ho sommato due delegati di funzioni, che ricordo devono avere stessa struttura come le interfacce ( stesso tipo di valore di ritorno e stesso tipo di argomenti ). Spero che con questi due esempi abbiate potuto capire i delegati, ho cercato di semplificare al massimo queste nozioni.
L’evento tipo a cui siamo abituati pensare è, per esempio, la pressione di un pulsante nell’interfaccia utente, qui un evento viene generato dal sottosistema a finestre che invia una notifica al gestore ( handler ) relativo. In generale si può pensare ad un evento come ad un cambio dello stato interno di un oggetto, vediamo come implementarlo:
public class GeneraEventi { public delegate void Delegato(object from, ArgomentiEvento args); public event Delegato mioEvento; public void GeneraEvento(ArgomentiEvento args) { mioEvento(this, args); } }
una classe che intenda gestire gli eventi della classe GeneraEventi può sottoscrivere il proprio metodo di gestione con il seguente codice:
GeneraEventi gi; .... gi += new GeneraEventi.Delegato( GestoreEventi );
In pratica la parola chiave event consente di applicare solo somme e sottrazioni ai delegati ( delegati multicast ) e mai uguaglianze, questo ovviamente per evitare di cancellare con una chiamata tutti i gestori eventi definiti prima. Se aveste dei dubbi o incertezze potete usufruire del forum sulla programmazione in C#. Nella prossima lezione vedremo di concludere l’esempio sulle WinForms con l’inserimento dei delegati ed eventi per gestire la scelta di un valore dall’elenco a discesa.
<< Lezione Precedente – Inizio Corso – Indice Lezioni – Lezione Successiva >>
Ottima guida base.
Ti consiglierei di inserire anche le stampe che vengono prodotte dal codice.
Grazie, è una lezione del corso su C# e quindi è basilare, l’output prodotto dal codice non voglio ci sia perché i miei lettori e spero studenti devono implementarlo e poi vedere il risultato.
Non credo di aver ben capito il concetto di delegate, in quanto non riesco bene ad immaginarmi dove possa essere applicato.
Esempi simili a quelli presenti sopra sono presenti anche sul libro Introducing to Visual C# dell’apress, ma anche con quelli, stesso problema.
io creo un delegato e ad esso vengono delegate le funzionalità di un altro metodo?
Dovrebbe funzionare così, mi chiedo allora dove posso applicare questo concetto.
grazie
[io creo un delegato e ad esso vengono delegate le funzionalità di un altro metodo?]
Le funzionalità di un altro o altri metodi, visto che i delegati si possono sommare e servono per la gestione degli eventi, quindi nelle applicazioni con form per gestire il da farsi quando ad esempio un utente fa clic su un pulsante o apre una casella a discesa o altro…
E al di fuori degli eventi ci sono altre applicazioni dei delegate?
Ma è il C# che utilizza i delegates ( puntatori a funzione ) per gestire gli eventi. Una volta che sai cosa fanno li puoi utilizzare quando ne hai bisogno, a me personalmente servono solo per gestire gli eventi, ma dagli esempi sopra ( che credo semplici ) puoi valutare quando utilizzarli.