A practical example of bullet 1 (null) might be if your run unit tests on your ViewModel. In such a case, there won't be a UI bound to your ViewModel, and if a test method (Test1
) updates a property without having subscribed to the PropertyChanged
event, you'll get a NullReferenceException
.
A (slightly less?) practical example of bullet 2 (threading) might be if a second unit test (Test2
) runs at the same time as Test1 above in a different thread. The second test does subscribe to the event some time before Test1 inadvertently triggers the event, but then unsubscribes again right in the middle of the if
test:
private void RaisePropertyChanged(string propertyName)
{
//1: Test1 changes a property, and triggers this event.
// Because Test2 earlier subscribed to the event, PropertyChanged is not null here
if (PropertyChanged != null)
{
//2: Test2 sneaks in from a different thread
// and *unsubscribes* from PropertyChanged, making it null again.
//3: Test1 then gets a NullReferenceException here,
// because there's no local "handler" variable that kept the original delegate.
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}