Gli eventi si basano sul concetto di delegati, un delegato è fondamentalmente una definizione di firma del metodo. È tutto. Come in un'interfaccia, come si definiscono le firme del metodo, ma non le si implementa, lo si fa in tutte le classi che ereditano quell'interfaccia.
Un delegato è una definizione per una firma del metodo, e per i quali è possibile definire come molti il metodo del corpo sei come, per esempio, dato questo (definizione del metodo firma) delegato:
public delegate void ChangingHandler (object sender, CarArgs ca);
È possibile definire corpi con questo delegato (metodo di definizione di firma) in quanto tale:
public void SomeMethodWhichCreatesADelegateBody()
{
ChangingHandler myChangingHandler = new ChangingHandler(
delegate(object sender, EventArgs e) { /* the method body for myChangingHandler */ }
);
}
questo è un vecchio stile di definire un delegato, però, ora è più leggibile da usare lambda al posto della parola chiave delegato per creare il corpo del metodo come ho fatto io , ma non è importante per il problema.
Ora gli eventi possono essere immaginati come delegati (definizione della firma del metodo) con un array di body a cui si fa riferimento come iscrizione all'evento, la sintassi per la sottoscrizione di un corpo del metodo a un evento è +=
e c'è anche la sintassi per la rimozione di un corpo di un metodo da una sottoscrizione di eventi che è -=
Quindi questo qui il codice definisce un array di corpo di per il delegato ChangingHandler (metodo di definizione firma):
public event ChangingHandler Change;
E si può sottoscrivere il corpo di (aggiungerli ai l'array) a questo gruppo di calli ng in un metodo:
public void SomeMethodWhichSubscribesADelegateBodyToAnEvent()
{
ChangingHandler myChangingHandler = new ChangingHandler(
delegate(object sender, EventArgs e) { /* the method body for myChangingHandler */ }
);
Change += myChangingHandler;
}
Ora tutta la ragione per l'evento per avere una serie di bodys metodo, che si arriva a definire e aggiungere come vuoi, è così che ogni volta che si verifica un evento interno dell'oggetto che possiede l'evento, quell'oggetto può eseguire tutti quei metodi per fare tutto ciò che si vuole fare quando si verifica quell'evento. L'oggetto proprietario dell'oggetto fa così:
if (Change != null) // You wouldn't access an array without making sure it wasn't null, would you?
{
Change(this, new CarArgs()); // This executes every method body in it's array using the signature definition the delegate defined.
// The delegate simply exists so this code knows the method signature
// so it can know how to call those method body's for you.
}
Nota, non è necessario creare in modo esplicito l'istanza del delegato. Puoi fare 'car.Change + = car_Change;' (questo è piuttosto idiomatico) – bruceboughton