Introduction
Here is a cool little trick to ensure compile time safety when raising property change notification events. Instead of using string
s as in "PropertyName
", we can very well use a lamda expression like () => PropertyName
.
Background
Property change notification is generally used in applications where XAML binding is used and hence these events are using to ensure two way binding with the UI as in MVVM design pattern.
Using the Code
Below is a typical implementation of INotifyPropertyChanged
interface which provides no compile time safety and client object passes string
to notify of a change in the property:
public class SampleClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _name;
public string Name
{
get { return _name; }
set
{
if (_name == value) return;
_name = value;
OnPropertyChanged("Name");
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
if (propertyName != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
So, in order to ensure compile time safety, we provide a simple overload for OnPropertyChanged
method as below, in turn using a helper method, which can very well be hosted in its own helper class. For the purpose of this example, I have it below:
protected virtual void OnPropertyChanged<T>(Expression<Func<T>> propertyExpression)
{
OnPropertyChanged(ExtractPropertyName(propertyExpression));
}
private string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
{
return (((MemberExpression)(propertyExpression.Body)).Member).Name;
}
And now, the client properties can be changed to raise the events like this:
public string Name
{
get { return _name; }
set
{
if (_name == value) return;
_name = value;
OnPropertyChanged(() => Name);
}
}