Search code examples
c#inotifypropertychangedstrong-typing

Is there a good strongly typed way to do PropertyChanged events in C#?


It must be a somewhat common event to change the name of a property and expect the Rename functionality in Visual Studio to take care of all the necessary renaming, except for the property name of the PropertyChanged event of INotifyPropertyChanged. Is there a better way to somehow get it strongly typed so you don't need to remember to manually rename it?


Solution

  • Edit: nameof arrived in c# 6. Yay!


    There is no nameof / infoof etc; this is much discussed, but it is what it is.

    There is a way to do it using lambda expressions in .NET 3.5 (and parsing the expression tree), but in reality it isn't worth the overhead. For now, I'd just stick with strings (and unit tests if you are determined not to break it).


    using System;
    using System.ComponentModel;
    using System.Linq.Expressions;
    using System.Reflection;
    class Program : INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;
        static void Main() {
            var p = new Program();
            p.PropertyChanged += (s, a) => Console.WriteLine(a.PropertyName);
            p.Name = "abc";
        }
        protected void OnPropertyChanged<T>(Expression<Func<Program, T>> property) {
            MemberExpression me = property.Body as MemberExpression;
            if (me == null || me.Expression != property.Parameters[0]
                  || me.Member.MemberType != MemberTypes.Property) {
                throw new InvalidOperationException(
                    "Now tell me about the property");
            }
            var handler = PropertyChanged;
            if (handler != null) handler(this,
              new PropertyChangedEventArgs(me.Member.Name));
        }
        string name;
        public string Name {
            get{return name;}
            set {
                name = value;
                OnPropertyChanged(p=>p.Name);
            }
        }
    }