Updated – INotifyPropertyChanged – How to remove the Property Name String Code Smell

Note: I updated this blog entry because the first method ran into problem with StackFrames in release builds without .pbd files.  I did find a JIT Compiler workaround but would never suggest such a hack.

I have so much to share with you since my last blog entry. 

Went on a cruise to Alaska to write BBQ Shack and Ocean v2 Code Name: Glacier.  Only got off the ship once because I was having way too much fun programming!  OK, I need an intervention, let’s move past the cruise bit.  Looking to go out again in September, need another week with whales, glaciers, seals, bald eagles, room service and my computer.

BBQ Shack is an end to end WPF & Silverlight Line of Business application that I’ll be using for a few months to write many Code Project articles and create tutorial videos.  The new Ocean API feature set is insane!

Since I got back from the cruise, I have been pair programing with Rock Stars Rob Zelt, Laurent Bugnion, Josh Smith and Glenn Block.  There is nothing like pair programming.  If you have not tried this, schedule it today and get your “Geek-On.”

BBQ Shack is almost ready for release but I felt the need to take a day and do what I did on the cruise.  Think, think, dream, think and question everything.  Be willing to look critically at my code, motivations, assumptions and the horizon.

So kdawg02  (my Twitter call sign), what did you do Saturday and 1/2 of Sunday that prompted you to fire off a blog post?

One item I’ve been hearing about is the Code Smell of having to put property names in the call to the method that raises the property changed event for Model and ViewModel classes.

Typical de facto Standard WPF or Silverlight Property

''' <summary>
''' No ma, that's not my dirty socks, its my setter stinking up the code again.
''' </summary>
Public Property TestMeString() As String
    Get
        Return _strTestMeString
    End Get
    Set(ByVal Value As String)
        _strTestMeString = Value
        OnPropertyChanged("TestMeString")
    End Set
End Property

Developers have long not like having quoted strings in their code.  Some would agree this practice is a bonafided Code Smell. 

I have not minded this smell because I always generate my entity classes so I never really cared.  If a property needs to change for some reason, I just regenerate my entity code.

One easy solution I’ve considered is to define a private constant for each property name and then simply use the constant.  More work, but does make the code cleaner.

But What if You Could Write Properties Like This?

''' <summary>
''' Look Ma, no code smell in my setter!
''' </summary>
Public Property TestMeGetCurrentMethodName() As String
    Get
        Return _strTestMeGetCurrentMethodName
    End Get
    Set(ByVal Value As String)
        _strTestMeGetCurrentMethodName = Value
        OnPropertyChanged(MethodBase.GetCurrentMethod.Name.Remove(0, 4))
    End Set
End Property

Well, you can!

The System.Reflection.MethodBase.GetCurrentMethod call gives us access to a wealth of information at runtime, including the name of the currently running method.  In our case the property setter.

The name of this property setter is, “set_TestMeGetCurrentMethodName.”  So by removing the first four characters the current property name is passed to the base classes OnPropertyChanged event handler.

Kind of anti-climatic isn’t it…

What is Performance Hit?

Below are 11 runs each doing 100 more iterations than the previous run.

The first result is the OnPropertyChanged(“TestMeString”) method.

The second result is the OnPropertyChanged(MethodBase.GetCurrentMethod.Name.Remove(0,4)) method.

The run is a release build, without any .pdb files, running from the command line.  I added some string manipulation code in the PropertyChangedEvent handler to simulate actual real world code that actually does some processing in the event handler.

When looking at the results the double quoted string method runs faster. 

But, do you really care about .4 milliseconds on 100 property changed events as in the second iteration?  Most WPF and Silverlight applications I’ve seen only raise one or two property changed events at a time. 

Note: If you have an application that has 100’s of events per second or more like real-time graphing applicaitons, I would not use this method for performance reasons.  Instead, go with string constants for the property names or double quoted strings if you like that better.

ReleaseModeCodeUpdated 

Where Are We

Want to thank the WPF Disciples who commented heavily and showed me holes in my first attempt.

I did receive a comment from Tamir Khason that he categorized as a gut feeling rather than known fact but am including it here for completeness, “There could be issues with reliability of reflection for production environment where assemblies can be obfuscated, delayed signed etc.”  Thanks for the heads up Tamir!

I’ve re-posted this blog entry to gain developer interest in finding a solid solution to this “Code Smell” issue without any external dependencies or Dependency Properties.

Other Solutions

Daniel Vaughan’s

Jonas Follesoe’s

Mike Brown’s

Neil Mosafi’s  (Be sure to read the comments on this blog post)

Peter O’Hanlon would like to see

public string Name

{

  get; [Notify]set;

}

Download

After downloading you must change the file extension from .doc to .zip.  This is a requirement of WordPress.com

Source Code (51KB)

Have a great day,

Just a grain of sand on the worlds beaches.

3 Responses to Updated – INotifyPropertyChanged – How to remove the Property Name String Code Smell

  1. [...] has been much discussion’s around removing the property name string code smell from INotifyPropertyChanged implementations. Reflection is slow, and various techniques using [...]

  2. [...] Shifflett предложил иной подход в своей статье. Он предложил брать имя свойства используя [...]

  3. atverma says:

    Property name code smell can be removed using Lambda Expressions. The link is http://www.atulverma.com/2010/05/inotifypropertychanging-and_04.html

Follow

Get every new post delivered to your Inbox.

Join 245 other followers