2009-04-24 3 views
6

Wenn ich ein Ereignis in Visual Studio implementieren, ist Resharper so freundlich, um einen Event Invocator für mich zu erstellen. Ich habe dies in der Regel mit der Hand in der Vergangenheit, und meine invocators sah immer wie dieseEvent Invocators in C#

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

aber die Invocator von ReSharper erstellt sieht wie folgt aus (bereinigt ein wenig von Hand)

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

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

Sie die Leute bei Jetbrains wissen etwas über C# Ich weiß nicht? Gibt es einen technischen Vorteil für die lokale Variable oder ist es nur ein Artefakt, dass sie den Code automatisch generieren müssen?

Antwort

8

Ja. Sie wissen, dass sich die Anzahl der Abonnenten eines Ereignisses zwischen dem "if" und dem Aufruf des Event-Handlers ändern kann. Sie erfassen es in einem lokalen, wo es sich nicht mehr ändert.

+0

sind u sicher? Nicht beide "zeigen" auf dieselbe Aufrufliste? – BFree

+1

Nicht unbedingt. Die gesamte Liste könnte sich im Allgemeinen ändern. Beachten Sie, dass ReSharper ein "allgemeines" Werkzeug ist. Sie scheinen davon auszugehen, dass das einzige, was mit dem Ereignis passiert, + = und - = ist. Vielleicht ja, vielleicht auch nicht, aber der "ReSharper" Weg deckt alle Grundlagen ab. –

+1

Eigentlich ist die Anzahl der Teilnehmer egal, das kümmert sich der Delegierte selbst. Die Tatsache, dass der Delegat null ist, wenn keine Abonnenten vorhanden sind, ist jedoch wichtig. Wenn keine Abonnenten vorhanden sind, ist das Feld null. Sie kopieren eine Nullreferenz, wenn also ein Abonnent nach dem hinzugefügt wird, wenn Sie es nur nicht sehen, wird nicht fehlschlagen. –

5

Ich denke, John Saunders hat wahrscheinlich die beste Antwort.

Für die Aufzeichnung, schreibe ich nicht einmal "Invocators" mehr. Ich habe Erweiterungs-Methoden, die es für mich tun, und ich rufe einfach PropertyChanged.Fire(this, "propName");

Siehe this article für weitere Informationen.

+2

Hey, das ist cool. Froh, dass ich gefragt habe. – MichaC

+0

Haben Sie die Möglichkeit, das Verhalten des Event Invocators hier zu überschreiben, nicht komplett weg? Sie haben keine Möglichkeit, das Verhalten in abgeleiteten Klassen zu ändern. – bberger

+0

@bberger Ich nehme an, aber das ist selten. Wenn Sie erweiterbares Verhalten benötigen, dann machen Sie es auf die alte Art und Weise? –

1

Dies ist nur ein Problem für Multithreading. Dies schützt Sie in einer Multithread-Umgebung.

Nehmen wir zum Beispiel folgendes Szenario vor:

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

nun ein zweiter Thread Abo kündigt hier, den Event-Handler zu modifizieren ....

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