Refactor-proof property references in .Net

So I'm playing around with WPF/Silverlight and find it quite annoying that you need to provide the string-based name of a property when raising your INotifyPropertyChanged events.  So you end up with code like this:

public partial class MyClass : System.ComponentModel.INotifyPropertyChanged {

        protected internal void OnPropertyChanged(string propertyName) {
            if (PropertyChanged == null) return;
            PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }

        private decimal _myProperty;

        public virtual decimal MyProperty {
            get { return _myProperty; }
            set {
                if (_myProperty.Equals(value)) return;
                _myProperty = value;
                OnPropertyChanged("MyProperty"); // <-----  This is annoying
            }
        }
  }

The problem here is that you now have a string-based reference to your property name. If you ever change the name of your property, you must remember to change the string. And if you don't remember -- there are no build-time errors to stop you. Thus, there is risk to any refactoring efforts -- something which I like to avoid!

So, how do you fix this. Well, one fairly straightforward way is to use expression trees / lambas to derive the name of your property from an actual reference.  In the following code example, I've added a method that takes a lamba and returns the string-based name of the property. 

private string GetRefactorproffPropertyName<T>(Expression<Func<T>> property) {
       LambdaExpression lambdaExpression = (LambdaExpression)property;
      var memberExpression = lambdaExpression.Body as MemberExpression 
                                    ?? ((UnaryExpression)lambdaExpression.Body).Operand as MemberExpression;           
      return memberExpression.Member.Name;
}
       

Now I can modify my property setter like this:

public virtual decimal MyProperty {
      get { return _myProperty; }
      set {
           if (_myProperty.Equals(value)) return;
           _myProperty = value;
           OnPropertyChanged(GetRefactorproffPropertyName(() => MyProperty)); // <--- this is better (compile-time check)
     }
}

Some references: http://stackoverflow.com/questions/3558974/select-a-model-property-using-a-lambda-and-not-a-string-property-name

http://stackoverflow.com/questions/3567857/why-are-some-object-properties-unaryexpression-and-others-memberexpression