Magari vi sembrerà assurdo, ma non ho ben capito quale sia la differenza tra un evento e un delegato...
Me lo protreste spiegare?
Grazie mille.
Ciao
Magari vi sembrerà assurdo, ma non ho ben capito quale sia la differenza tra un evento e un delegato...
Me lo protreste spiegare?
Grazie mille.
Ciao
Qui è molto chiaro
- http://msdn.microsoft.com/en-us/library/ms366768.aspx
- http://msdn.microsoft.com/en-us/library/awbftdfh.aspx
Quando si parla di delegate si può intendere due cose:
- il tipo delegate: è un tipo di dato che rappresenta la firma di una funzione
- un oggetto di tipo delegate: è un oggetto che punta a una funzione conforme al tipo delegato
Gli eventi sono oggetti cui ci si può iscrivere e attendere che, al verificarsi dell'evento, venga invocato il metodo di callback che è definito durante la registrazione all'evento.
Cioè, l'iscrizione avviene associando un event handler (o callback). L'event handler (cioè una funzione che tu hai definito) deve essere conforme al tipo delegato con cui l'event handler è stato dichiarato per l'evento.
Per chiarimenti, guarda gli esempi di questa pagina:
- http://msdn.microsoft.com/en-us/library/8627sbea.aspx
E, in particolare, ti faccio notare
// Declare the delegate (if using non-generic pattern).
public delegate void SampleEventHandler(object sender, SampleEventArgs e);
// Declare the event.
public event SampleEventHandler SampleEvent;
"Il problema delle citazioni su Internet è verificarne l'autenticità." (Winston Churchill)
Ti consiglio di fare un programma di prova per mettere in pratica quello che c'è scritto su msdn.
Ne ho fatto uno banalissimo, cercando di seguire la forma presentata negli esempi:
Main.css
Persona.cscodice:using System; namespace Tests { class MainClass { public static void Main(string[] args) { MainClass mc = new MainClass(); Console.WriteLine("Hello World!"); Persona p = new Persona(10); p.CrescitaPersona += new Persona.CrescitaPersonaGestore(mc.InRispostaAllaCrescita); Console.WriteLine("La persona creata ha {0} anni", p.Eta); p.CresciUnAnno(); } public void InRispostaAllaCrescita(object sender, PersonaEventArgs pea){ Console.WriteLine("{GESTORE EVENTO} >>> " + pea.Text); } } }
Ho testato in MonoDevelop.codice:using System; namespace Tests { public class PersonaEventArgs{ public string Text{ get;set; } public PersonaEventArgs(string s){ Text = s; } } public class Persona { public int Eta{ get; set; } public delegate void CrescitaPersonaGestore(object sender, PersonaEventArgs pea); public event CrescitaPersonaGestore CrescitaPersona; public Persona(int etaIniziale) { Eta = etaIniziale; } public void CresciUnAnno(){ Eta++; RaiseEvent(); } public void RaiseEvent(){ CrescitaPersona( this, new PersonaEventArgs("La persona è cresciuta. Ora ha " + Eta + " anni") ); } } }
Ciao
"Il problema delle citazioni su Internet è verificarne l'autenticità." (Winston Churchill)
Io in effetti con delegate intendevo l'oggetto di tipo delegate, che in pratica è una sorta di puntatore a funzione. Ma quello che ancora non capisco è perchè si dovrebbe usare un event invece di un oggetto delegate (tranne forse per il fatto che l'evento si può dichiarare in una interfaccia).Originariamente inviato da robyonrails
Qui è molto chiaro
- http://msdn.microsoft.com/en-us/library/ms366768.aspx
- http://msdn.microsoft.com/en-us/library/awbftdfh.aspx
Quando si parla di delegate si può intendere due cose:
- il tipo delegate: è un tipo di dato che rappresenta la firma di una funzione
- un oggetto di tipo delegate: è un oggetto che punta a una funzione conforme al tipo delegato
Gli eventi sono oggetti cui ci si può iscrivere e attendere che, al verificarsi dell'evento, venga invocato il metodo di callback che è definito durante la registrazione all'evento.
Cioè, l'iscrizione avviene associando un event handler (o callback). L'event handler (cioè una funzione che tu hai definito) deve essere conforme al tipo delegato con cui l'event handler è stato dichiarato per l'evento.
Per chiarimenti, guarda gli esempi di questa pagina:
- http://msdn.microsoft.com/en-us/library/8627sbea.aspx
E, in particolare, ti faccio notare
Cioè, usando un oggetto delegate non si possono fare le stesse cose che si fanno con un oggetto event? Quando tu dici che ci si iscrive all'evento in pratica intendi che si "aggiunge" un event handler, che altro non è che una un metodo che io associo all'evento. Ma allora lo stesso metodo non posso "linkarlo" ad un oggetto delegate invece che ad un oggetto event, e poi ottenerne l'esecuzione quando si verifica la condizione?
Insisto sulla questione perchè temo ci sia qualcosa di importante che mi sfugge...
L'evento serve a far si' che io possa associare dinamicamente un metodo della classe A ad un oggetto event di una classe B, in modo che questo metodo venga eseguito quando l'oggetto event viene richiamato (ovvero quando si verifica una condizione).
E la stessa cosa posso fare se al posto dell'oggetto event nella classe B ho un oggetto delegate, e io gli linko un metodo della classe A.
In cosa sbaglio?
Ah, ora ho capito il tuo dubbio. In effetti la differenza è sottile.
http://blog.monstuff.com/archives/000040.html
Nel link soprastante vengono descritti diversi punti in cui gli event differiscono dai delegate.
In particolare:
Qui ci sono altre cose interessanti: http://www.yoda.arachsys.com/csharp/events.htmlLooking at the C# keywords list on MSDN, It turns out that event is only a modifier.
An event can be included in an interface declaration, whereas a field cannot.
Furthermore, an event can only be invoked from within the class that declared it, whereas a delegate field can be invoked by whoever has access to it.
Also, events come with a pair of accessor methods. They have an add and remove method.
E, in particolare, i paragrafi "A shortcut: field-like events" e "Thread-safe events".
Comunque non preoccuparti troppo, sono meccanismi molto simili.
"Il problema delle citazioni su Internet è verificarne l'autenticità." (Winston Churchill)
Ah, bene, ora sono più tranquillo.
A quanto pare le differenze (almeno quelle esteriori, poi se il compilatore "vede" eventi e delegati in maniera del tutto differente, questi sono solo affari suoi :P) sono fondamentalmente quelle che avevo notato io.
In effetti avevo notato anche che per eseguire un evento dovevo farlo dalla classe in cui l'avevo dichiarato, non funziona neanche se tento di eseguirlo da una classe derivata (tant'è vero che ho dovuto fare un metodo runEvent() dichiarato protected che non fa altro che eseguire l'evento). Mentre i delegate posso manipolarli come e dove mi pare.
Ultima domanda: mettiamo il caso che il abbia un event (o un delegate, a questo punto) con uno o più metodi linkati, e che io voglia eliminarli tutti, senza preoccuparmi di quali e quanti siano. Posso semplicemente porre l'evento (o il delegato) uguale a null? Ho provato e funziona, ma voglio assicurarmi che non ci siano "controindicazioni"...
Grazie ancora,
ciao
No, nessuna controindicazione.Originariamente inviato da MonsterMash
Ultima domanda: mettiamo il caso che il abbia un event (o un delegate, a questo punto) con uno o più metodi linkati, e che io voglia eliminarli tutti, senza preoccuparmi di quali e quanti siano. Posso semplicemente porre l'evento (o il delegato) uguale a null? Ho provato e funziona, ma voglio assicurarmi che non ci siano "controindicazioni"...
"Il problema delle citazioni su Internet è verificarne l'autenticità." (Winston Churchill)
Sono in tilt!![]()
Ho ereditato con C# il controllo combobox per far comparire una datagridview al posto della listview e la cosa funziona in maniera abbastanza banale.
La cosa che mi sta facendo impazzire è la voglia di intercettare gli eventi Enter e Leave del ComboBox in modo che :
-Enter si attivi solo quando entro effettivamente nel combobox
-Leave si attivi solo quando passo ad un altro controllo (che non sia la datagridview abbinata alla comboBox)
In pratica una volta intercettato il dropdown, cedo il focus alla datagridview, ma si scatenerebbe anche l'eventuale evento Leave impostato sul combobox (che vorrei appunto sospendere temporaneamente).
Viceversa quando seleziono una riga dalla datagridview (visualizzata dall'evento dropdown) e ricedo il focus alla combobox, si scatenerabbe l'eventuale evento Enter della comboBox.
Siccome non posso sapere a priori come verranno chiamato i gestori degli eventi Enter e Leave, cercavo un modo pe scorrere a runtime la lista degli eventi abbinati al controllo e 'parcheggiare' gli eventi di questo tipo per poi riattivarli alla fine delle operazioni 'personalizzate'.
Ho la netta sensazione di perdermi in un bicchiere d'acqua...ma mi sono ormai cavato gli occhi per cercare una soluzione che mi aspettavo abbastanza banale.
Ditemi che sono solo un po' stanco...
ho risolto.
Non nella maniera che volevo e che mi aspettavo fattibile, ma mi sono tolto dalle secche.
Mi rimane comunque il dubbio: se volessi scorrere la lista dei gestori eventi legati ad un controllo ed individuare quale tra questi gestisce l'evento OnEnter, ho qualche possibilità?
Se qualche esperto ha dei consigli, mi farebbe piacere capire...
Per ora grazie