2

I've noticed in all the samples I've seen for events in C# that firing the event is written as:

PropertyChangedEventHandler handler = PropertyChanged;
if(handler != null)
    handler(this, new PropertyChangedEventArgs(propertyName));

What is the different between that and just writing:

if(PropertyChanged != null)
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
Dirk Dastardly
  • 1,017
  • 2
  • 12
  • 23
  • 4
    The reason is stated as a part of the question here: http://stackoverflow.com/questions/786383/c-sharp-events-and-thread-safety There's also a link to blog post of Eric Lippert explaining it: http://blogs.msdn.com/b/ericlippert/archive/2009/04/29/events-and-races.aspx – Dirk Apr 23 '15 at 13:29
  • 1
    @JenishRabadiya: It can be null. It is an event. – Patrick Hofman Apr 23 '15 at 13:30
  • @PatrickHofman Yes you are right. It's from `INotifyPropertyChanged` Interface. – Jenish Rabadiya Apr 23 '15 at 13:36

2 Answers2

8

In your second example, you call the getter of PropertyChanged twice. In a multithreaded environment it is possible, that the value is changed in between the calls.

This is prevented in your first example, by first making a local copy.

GvS
  • 52,015
  • 16
  • 101
  • 139
  • But in first case(code snippet) if some thread assign null to `PropertyChanged` wouldn't it get assigned to `handler` instance as delegates are behaving like reference type. – Jenish Rabadiya Apr 23 '15 at 13:40
  • @JenishRabadiya The handler would still point to the original delegate. Think of a delegate as an array (of methods to call). If you set one variable previously pointing to the array to null, this does not change another variable pointing to the same array. – GvS Apr 23 '15 at 13:44
  • That seems confusing to me when I read [msdn documentation](https://msdn.microsoft.com/en-us/library/ms173172.aspx). Documentation quotes `Delegate types are derived from the Delegate class in the .NET Framework.` and delegates are reference type than how is possible. – Jenish Rabadiya Apr 23 '15 at 13:50
  • @JenishRabadiya Delegates are immutable. So once you created it you can't modify it. New instance will be created when someone subscribes to an event, which means your copy of the event is untouched. – Sriram Sakthivel Apr 23 '15 at 14:12
  • @SriramSakthivel Thanks I was unaware about that fact. – Jenish Rabadiya Apr 23 '15 at 14:30
4

In the second case, the value of PropertyChanged might be mutated between the if and the invoke if you're running multithreaded. It is not recommended.

You might also try initializing your event handler to have an empty handler like this:

public EventHandler<PropertyChangeEventArgs> PropertyChanged = (s, e) => { };

which means it will never be null, so you can just fire it is as.

plinth
  • 48,267
  • 11
  • 78
  • 120
  • *which means it will never be null* unless you set it to. Don't forget you can set it to null explicitly inside the class where event is declared. – Sriram Sakthivel Apr 23 '15 at 13:35