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: