how does PropertyChangedEventHandler work?
Asked Answered
B

3

20

This is a really simple question, but I was wondering if someone could explain what the 4th line is actually doing? so the first line gives an event to the handler. I don't really know in what circumstances handler will return null or what the last line does.

When you pass the handler your object and which property changed, what does it do with them?

PropertyChangedEventHandler handler = PropertyChanged; //property changed is the event

if (handler != null)
{
    handler(this, new PropertyChangedEventArgs(name));
}

I assume I used this to get this code but I would like to understand what it is doing fully.

Brady answered 19/7, 2013 at 1:10 Comment(4)
Without context it is hard to tell. What framework are you using? That isn't part of the BCL, its probably some MVVM framework that you're examining/using.Circuitous
That doesn't look like anything special to PropertyChangedEventHandler. That's just how handlers work.Chloro
Will's comment is nonsensical. This is tagged WPF. PropertyChangedEventHandler is in System.ComponentModel. There's no such thing as an MVVM framework -- MVVM is an architectural pattern that is useful with but isn't necessary for WPF. Anyway, this question is about how event handlers work in C# and the answer isn't specific to any particular event or framework.Mellissamellitz
"the first line gives an event to the handler" -- no, it declares a variable, handler, and initializes it with the value of PropertyChanged ... which might be null.Mellissamellitz
U
43

If you just did:

PropertyChanged(this, new PropertyChangedEventArgs(name))

you would get a NullReferenceException if no one was subscribed to the event PropertyChanged. To counteract this you add a null check:

if(PropertyChanged != null)
{
    PropertyChanged(this, new PropertyChangedEventArgs(name))
}

Now, if you are using multi-threading someone could unsubscribe between the null check and the calling of the event, so you could still get a NullReferenceException. To handle that we copy the event handler to a temporary variable

  PropertyChangedEventHandler handler = PropertyChanged;
  if (handler != null)
  {
    handler(this, new PropertyChangedEventArgs(name));
  }

Now if someone unsubscribes from the event our temporary variable handler will still point to the old function and this code now has no way of throwing a NullReferenceException.

Most often you will see people use the keyword var instead, this makes it so you don't need to type in the full type of the temporary variable, this is the form you will see most often in code.

  var handler = PropertyChanged;
  if (handler != null)
  {
    handler(this, new PropertyChangedEventArgs(name));
  }
Ulrikaumeko answered 19/7, 2013 at 1:21 Comment(2)
In the race condition, wouldn't copying the handler then call a function that somebody just specified should no longer be called? Is that just the accepted way of doing business or is there something that I'm missing?Natter
@ZachMierzejewski Yes it is the expected behavior. It is the responsibility of the subscriber to know that even though unsubscribed if in a multi-threaded situation you could still get a final call to the method. All events of classes built in to .NET behave with this pattern.Ulrikaumeko
K
10

PropertyChanged is the event that was declared like this, according to its definition in the interface:

public event PropertyChangedEventHandler PropertyChanged;

Events that are defined like that are actually a syntactic sugar for a list of event handlers you can add a delegate (that is a reference to a function) to by subscribing, or remove a delegate by unsubscribing.

Now, when you call an event, i.e. PropertyChanged(...), then what happens internally is that every delegate in that internal list is called separately with the parameters. This will tell all the subscribers of your event that the event happened.

Now, the reason for the whole thing with the handler variable is, that PropertyChanged can be null. If nothing subscribed to it, then calling the event (or rather the event handler list) would not work, so this is just a way to ensure that you can actually execute the handler.

Kearse answered 19/7, 2013 at 1:19 Comment(0)
E
6

handler can be null if no handlers are subscribed to the event, the fourth line raises the event for the property name given (which executes all subscribed handlers).

Usually the WPF framework will subscribe to PropertyChanged when you use bindings, so it can update the binding once the bound property changes.

Euton answered 19/7, 2013 at 1:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.