(Questo è tutto da una prospettiva di C#.)
Ho un article about the differences between events and delegates. Questo copre tutto quanto menzionato di seguito in molti più dettagli.
Fondamentalmente mi piace pensare a un evento come se fosse una proprietà: è un paio di metodi, tutto qui. Invece di get/set, un evento ha add/remove - che significa "aggiungi questo gestore di eventi" e "rimuovi questo gestore di eventi". Al centro, è tutto un evento.
C# ha anche eventi sul campo come che sono una scorciatoia:
public event EventHandler Foo;
dichiara sia un campo e un evento, con una quasi banale aggiunta/rimozione implementazione. All'interno della classe, facendo riferimento a Foo
si fa riferimento al campo. Al di fuori della classe, facendo riferimento a Foo
si riferisce all'evento.
L'idea di base è che un evento consenta ad altro codice di iscriversi e annullare l'iscrizione, trasferendo un delegato (l'evento gestore). Di solito, l'abbonamento viene implementato creando un nuovo delegato multicast contenente lo precedente elenco di gestori di eventi e il nuovo.Quindi, se siete memorizzare i gestori di eventi in un campo chiamato myEventHandlers
, l'attuazione di sottoscrizione potrebbe essere:
myEventHandlers += value;
Allo stesso modo disiscrizione di solito comporta la creazione di un nuovo delegato multicast senza il gestore specificato:
myEventHandlers -= value;
Quindi, quando si desidera aumentare/attivare l'evento, è sufficiente chiamare il delegato multicast, di solito con un controllo di nullità per evitare che venga generata un'eccezione se nessuno si è iscritto:
EventHandler handler = myEventHandlers;
if (handler != null)
{
// You could pass in a different "sender" and "args" of course
handler(this, EventArgs.Empty);
}
Utilizzando gli eventi, gli abbonati non si conoscono e non possono sollevare l'evento da soli (in genere). In altre parole, è uno schema di incapsulamento, a cui è stato dato lo status sia nella lingua che nella piattaforma.
No, gli eventi * non sono * delegati. Gli eventi sono metodi di aggiunta/rimozione, in pratica. Dire che gli eventi sono delegati è come dire che le proprietà sono campi. –
Le proprietà IMHO DEVONO comportarsi come i campi, esattamente come gli eventi si comportano come delegati multicast. Altrimenti è fuorviante per l'utente di una classe poiché la proprietà e l'accesso al campo sono simili nell'origine così come l'invio di eventi e l'invio di delegati. Ciò non significa che una proprietà o un evento debba utilizzare l'implementazione predefinita (campo di supporto, supporto multicast). Significa semplicemente "proprietà/campo: ottieni/imposta un valore senza effetti collaterali" e "evento/delegato: esegui una richiamata". Con proprietà/eventi il linguaggio ti dà un sacco di corda che puoi usare in modo ragionevole o impiccarti. – froh42