I think almost every .NET developer is familiar with INotifyPropertyChanged interface. Typical implementation of this interface looks more or less like that:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class NotifyPropertyBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged( Expression<Func<object>> propertyExpression ) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler( this, new PropertyChangedEventArgs( GetPropertyName( propertyExpression ) ) ); } private string GetPropertyName( Expression<Func<object>> propertyExpression ) { var unaryExpression = propertyExpression.Body as UnaryExpression; var memberExpression = unaryExpression == null ? (MemberExpression)propertyExpression.Body : (MemberExpression)unaryExpression.Operand; var propertyName = memberExpression.Member.Name; return propertyName; } } |
Thanks to lambda expressions we can get rid of so called “magic” strings when rising PorpertyChange event.
1 2 3 4 5 6 7 8 9 10 11 |
private int _myProperty; public int MyProperty { get { return _myProperty; } set { if (_myProperty == value) return; _myProperty = value; OnPropertyChanged( ( ) => MyProperty ); } } |
However, with .NET 4.5 we can even get rid of lambda expressions itself. Everything thanks to CallerMemberNameAttribute, which provides us information about caller of given method. Now we can rewrite NotifyPropertyBase class as follows
1 2 3 4 5 6 7 8 9 |
public class NotifyPropertyBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged( [CallerMemberName] string propertyName = null ) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler( this, new PropertyChangedEventArgs( propertyName)); } } |
From this moment we can call OnPropertyChanged method without any arguments
1 2 3 4 5 6 7 8 9 10 11 |
private int _myProperty; public int MyProperty { get { return _myProperty; } set { if (_myProperty == value) return; _myProperty = value; OnPropertyChanged(); } } |
and thanks to CallerMemberName attribute, argument propertyName will be filled with appropriate value.
Source code for this post can be found here