2009-04-24 9 views
6

Quando implemento un evento in Visual Studio, Resharper è abbastanza gentile da offrirmi di creare un event call per me. Io di solito fatto questo a mano, in passato, e le mie invocators sembrava sempre cosìInvocatori di eventi in C#

private void InvokePropertyChanged(PropertyChangedEventArgs e) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, e); 
     } 
    } 

ma l'evocatore creato da ReSharper si presenta così (ripulito un po 'a mano)

private void InvokePropertyChanged(PropertyChangedEventArgs e) 
    { 
     PropertyChangedEventHandler changed = PropertyChanged; 

     if (changed != null) 
     { 
      changed(this, e); 
     } 
    } 

Fare la la gente di jetbrain sa qualcosa di C# non lo faccio? C'è qualche vantaggio tecnico nell'avere la variabile locale, o è solo un artefatto di loro dover generare automaticamente il codice?

risposta

8

Sì. Sanno che il numero di abbonati a un evento può cambiare tra "se" e la chiamata al gestore di eventi. Lo catturano in un locale, dove non cambia più.

+0

are u sicuro di questo? non entrambi "puntano" alla stessa lista di invocazione? – BFree

+1

Non necessariamente. L'intero elenco potrebbe cambiare, in generale. Si noti che ReSharper è uno strumento "generale". Sembra che tu stia assumendo che l'unica cosa che accade con l'evento sia + = e - =. Forse sì, forse no, ma il modo "ReSharper" copre tutte le basi. –

+1

In realtà il numero di abbonati non importa, che è curato dal delegato stesso. Il fatto che il delegato sia nullo se non ci sono abbonati, tuttavia, è importante. Se non ci sono abbonati, il campo è nullo. Copi un riferimento null, quindi se un abbonato viene aggiunto dopo il caso in cui non lo vedrai semplicemente non fallirà. –

5

Penso che John Saunders abbia probabilmente la migliore risposta.

Per la cronaca, non scrivo più nemmeno "Invocatori". Ho metodi di estensione che lo fanno per me, e mi limito a chiamare PropertyChanged.Fire(this, "propName");

Vedere this article per maggiori informazioni.

+2

Ehi, va bene. Sono contento di averlo chiesto. – MichaC

+0

Non ti toglie completamente la possibilità di sovrascrivere il comportamento dell'evocatore di eventi qui? Non hai alcuna possibilità di cambiare il comportamento nelle classi derivate. – bberger

+0

@bberger Suppongo, ma farlo è raro. Se hai bisogno di un comportamento estensibile, allora fallo alla vecchia maniera? –

1

Questo è solo un problema per il multithreading. Questo ti protegge in un ambiente multithread.

Per esempio, prendete questo scenario:

if (PropertyChanged != null) // PropertyChanged has one subscriber here 
{ 

Ora, un secondo thread unsubscribes qui, modificando il gestore di eventi ....

PropertyChanged(this, e); // This is no longer valid! 
}