Removing strings when using INotifyPropertyChanged

Update: I wrote this article a long time ago, while I was playing with an idea. Another possibility in C# 6.0 is to use the nameof() utility method.

I had an interesting idea this morning about adding an extension that would allow me to get a method name without using a string value.

The intended use was to add some safety to the use of the INotifyPropertyChanged interface. Most implementations of this interface use a string when calling OnPropertyChanged(“…”). I wanted to do something that would allow me to use refactoring tools to change the name of a property without having to update a string value manually.

As a novelty, I decided to implement it as an extension to all objects. It could just as easily be a utility method.

///
/// UtilExtensions is a class of utility extensions
///
public static class UtilExtensions
{   /// The ToName extensions is added to all non value-type objects.
    public static string ToName<T, P>(this T obj, Expression<Func<T, P>> action) where T : class
    {
        string retVal;

        if (action.Body is MethodCallExpression)
        {
            retVal = ((MethodCallExpression)action.Body).Method.Name;
        }
        else if (action.Body is MemberExpression)
        {
            retVal = ((MemberExpression)action.Body).Member.Name;
        }
        else
        {
            throw new Exception("Unable to determine use: " + action.Body.GetType().ToString());
        }

        return retVal;
    }
}

It would be used like this:

public string MyName
{
    get { return _myName; }
    set {
        _myName = value;

        OnPropertyChanged(this.ToName(x => x.MyName));
    }
}

Apparently, this isn’t a new idea.

While I was researching this I discovered (from other blogs) that there is a new attribute in .NET 4.5 that would help with this issue. The [CallerMemberName] attribute can be used to automatically enter an optional parameter value with the name of the calling method.

It would look like this:

/// Execute the PropertyChanged event.
/// The [CallerMemberName] attribute is used to automatically supply the caller method name.
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(name));
    }
}

Links: