Pivello ha scritto:
Dalla tua risposta penso che mi mancano ancora parecchie basi prima di andare avanti con i delegati.
Provo a semplificare il concetto io.
Se hai gestito eventi all'interno di uno dei tuoi programmi, di fatto hai già sfruttato la funzionalità dei
delegati.
Supponendo che tu abbia creato un componente che, a un certo punto, ha bisogno di
segnalare un evento o di ricorrere all'esecuzione di una logica esterna alla tua classe, che magari possa essere personalizzata da un altro sviluppatore.
Ti occorre quindi un mezzo per "delegare" (appunto) questa esecuzione.
Quando gestisci il click su un pulsante, ad esempio, non fai altro che
assegnare a tale pulsante il metodo preposto alla gestione del click.
Ovvio che si farebbe prima a chiamare il tuo metodo direttamente, ma questo vuol dire che ogni pulsante dovrebbe legarsi a doppio filo con qualsiasi logica custom debba essere eseguita a fronte del clic. Le operazioni che vengono svolte al clic di un pulsante sono infinite, quindi non è possibile creare un pulsante per ogni esigenza: si crea quindi un pulsante unico e generico, e quando viene cliccato, questo andrà a chiamare un metodo fornito da te, che dovrà quindi essere preventivamente assegnato al pulsante, per segnalare che è avvenuto il click, e sarai tu - all'interno del suddetto metodo - a decidere cosa fare a fronte di quell'evento.
Ma come avviene questa assegnazione? Grossomodo tramite qualcosa di non difforme dalla valorizzazione di una variabile o di una proprietà, solo che
ciò che vai ad assegnare non è un intero, una stringa o un booleano, bensì
il riferimento a un metodo: vi sarà quindi una variabile specifica che, come valore, conterrà un riferimento al metodo assegnato per gestire il click, riprendendo l'esempio sopra, e
tramite quel riferimento potrà essere invocato.
Ovviamente, il metodo che viene assegnato dovrà avere determinate caratteristiche: ad esempio, il click su un pulsante è un evento che prevede il passaggio di un solo parametro per valore, contenente l'oggetto che ha scatenato l'evento stesso più una struttura di argomenti aggiuntivi; non sarà quindi possibile assegnare all'evento un metodo senza parametri, o che contiene un numero diverso di parametri o parametri di tipo diverso... questa è la
"firma" del metodo.
La "firma" del metodo è importante in quanto il componente che ha bisogno di invocare il metodo lo farà passando i parametri attesi, e il metodo assegnato alla variabile che contiene il suo riferimento dovrà avere precisamente quei parametri.
Cosa stabilisce qual è la "firma" del metodo che ci si aspetta venga assegnato e poi invocato? Esattamente il
delegate di C#.
Creare un delegato in C# vuol dire definire un tipo che rappresenta la firma del metodo che
1) usata nella dichiarazione della variabile/proprietà/evento ci consente di ricevere in assegnazione un metodo esterno che rispetta quella firma;
2) in fase di invocazione, qualora tale riferimento sia assegnato, ci permette di passare esattamente i parametri che ci aspettiamo.
Vedi il delegato come una sorta di "contratto" che chi scrive il metodo e vuole assegnarlo, e chi invocherà tale metodo in seguito, dovrà rispettare in termini di numero e tipo dei parametri. Se il contratto non viene rispettato, il compilatore si rifiuta di accettarlo e segnala un errore.
Prova a riflettere su questi concetti ed eventualmente fai anche una ricerca online per individuare qualche tutorial alternativo che magari contiene un esempio maggiormente chiarificatore rispetto a quello contenuto nel libro in tuo possesso.
Ciao!