How to use INotifyPropertyChanged, the type-safe way (no magic string)

Implementation of the INotifyPropertyChanged interface is quite simple. There is only one event to implement. Take for example the following simple model class:

This is a pretty standard way to implement a bindable property. The problem here is the “Data” string to specify which property changed. If someone change the name of the property without changing the content of the string, the code will compile fine but won’t work. In a big application with may properties it can be hard to detect and find the problem.

The best solution is to rely on the compiler to warn us. But because the property name is a string it can’t. So let’s change that line with a type-safe one.


What is the trick? Raise is an extension method that takes a lambda expression to specify the name of the property in a type safe way. The Raise method resolve this expression to extract the name of the property and pass it to the PropertyChanged event.

All you have to do is to put this extension method in your code and the jib is done. Of course at the end a string will be used to raise the PropertyChanged event but because you don’t have to type it, you don’t have to maintain it.

5 thoughts on “How to use INotifyPropertyChanged, the type-safe way (no magic string)

  1. Very good idea! After I tried it out I have two hints:

    If the property is a value type you need an additional step to unbox the expression body:

    ((MemberExpression)((UnaryExpression)propertyExpression.Body).Operand).Member.Name

    The only reason why you must compile and execute the expression is to retrieve the sender. I would avoid this completely by simply adding the sender to the parameters:

    PropertyChanged.Raise(this, () => Data);

    I think adding the sender is better than creating code to retrieve it.

  2. Maybe this can be improve to keep a cache but in most enterprise application the cost is negligible.

    Of course most refactoring tool will catch it, but what if someone change a property name without refactoring? It will compile but won’t work.

Leave a Reply