Wenn wir MVVM verwenden, verwenden wir meistens die INotifyPropertyChanged-Schnittstelle, um die Benachrichtigung an die Bindungen zu senden, und die allgemeine Implementierung sieht folgendermaßen aus:
%Vor%Das funktioniert gut für mich, wenn ich den Code von den Experten lese - sie haben einen ähnlichen Code geschrieben:
%Vor%Ich würde gerne wissen, was genau der Grund für das Erstellen eines temporären Objekts für das PropertyChanged-Ereignis ist.
Ist es nur eine gute Übung oder sind andere Vorteile damit verbunden?
Ich habe die Antwort mit Jons Antwort und dem erklärten Beispiel gefunden:
C # verstehen: Ereignisse mit einer temporären Variable auslösen
Hier ist der Beispielcode, um dies zu verstehen:
%Vor%Sie erstellen kein temporäres Objekt . Sie verwenden eine lokale Variable, um eine Wettlaufsituation zu vermeiden.
In diesem Code:
%Vor% Es ist möglich, dass PropertyChanged
zu null
wird (aufgrund der letzten Abmeldung des Abonnenten) nach Nichtigkeitscheck, was bedeutet, dass Sie eine NullReferenceException
erhalten.
Wenn Sie eine lokale Variable verwenden, stellen Sie sicher, dass es sich bei dem Verweis, den Sie auf Nichtigkeit prüfen, um den gleichen Verweis handelt, den Sie zum Auslösen des Ereignisses verwenden, damit Sie keine Ausnahme erhalten. Es gibt immer noch eine Race-Bedingung, dass Sie am Ende Abonnenten anrufen, die gerade abgemeldet haben, aber das ist unvermeidlich.
Dies soll den seltenen Fall vermeiden, dass der letzte (oder einzige) Event-Handler zwischen dem Zeitpunkt, an dem Sie nach Null suchen, und dem Zeitpunkt, zu dem Sie das Event aufrufen, aus dem Event entfernt wird. Wenn das passiert, erhalten Sie NullReferenceException
.
Wenn Sie über Speicherlecks besorgt sind - seien Sie nicht - es ist nur eine Referenz, keine Kopie des Ereignishandlers.
Weitere Details finden Sie hier
Dies ist aus Gründen der Fadensicherheit eine gute Übung.
In Ihrem ursprünglichen Code ist es theoretisch möglich, dass ein separater Thread den PropertyChanged
-Handler nach der if
-Anweisung entfernt, aber vor das Ereignis ausgelöst wird die folgende Zeile. Dies würde NullReferenceException
verursachen.
Die zweite Probe beseitigt dieses Risiko.
Es macht nur einen Unterschied, wenn Multithread-Szenarien behandelt werden: Wenn der letzte Event-Handler nach der != null
-Prüfung abgemeldet wird, kann der tatsächliche Aufruf in Code 1 mit einer NullReferenceException ausgelöst werden.
Code 2 hat jedoch dieses Problem nicht, da Delegaten (das Konzept hinter Ereignissen) unveränderlich sind und daher der Wert der temporären Variablen sich nicht ändern kann.
Ich würde jedoch empfehlen, immer Variante 2 als Best Practice zu wählen - das könnte Ihnen in der Zukunft Kopfschmerzen ersparen; -)