A Better INotifyPropertyChanged Implementation
The INotifyPropertyChanged-interface and companions are a well know citizens of the .NET-framework. How do you implement this interfaces?. Does it look similar to this?
public class Person : INotifyPropertyChanged { private string firstname = ""; /* Other fields for the properties */ public event PropertyChangedEventHandler PropertyChanged; public string Firstname { get { return firstname; } set { firstname = value; OnPropertyChanged("FirstName"); } } /** Other properties **/ private void OnPropertyChanged(string propertyName) { var property = PropertyChanged; if (null != property) property(this, new PropertyChangedEventArgs(propertyName)); } }
This is a common pattern. Often it’s even uglier because the code in the ‘OnPropertyChanged’-method is copy & pasted into the property-implementation.
So what makes me sad about this common implementation?
1. First you need to implement the code in ‘OnPropertyChanged’ over and over. Of course you can build a base-class for this. However I try to be careful with inheritance. Therefore I really don’t like just inherit for this purpose.
2. The property name is a string and that pretty bad here: You have no assistance from the compiler. When you refactor the property-name or make a typo you have introduce a very subtle bug into your program. If your lucky you catch is with unit-test. But honestly, I concentrate my unit test on more important stuff than validating properties.
Now the goal is clear. I want a implementation which has this properties:
1. Reusing the code in the ‘OnPropertyChanged’-method without inheritance
2. Static type safety, my compiler should complain when I make a typo.
My effort resulted in this:
public string Firstname { get { return firstname; } set { firstname = value; PropertyChanged.Fire(this,()=>Firstname); } }
Now you can call “Fire” on all PropertyChangedEventHandler-events. The ‘Fire’-Implementation is an extension-method which implements the boiler-plate: Checking for null etc. To avoid the string as property-name you pass in a lambda-expression. This avoid typos and makes refactoring safer.
Of course it’s not perfect. You could still pass something wrong with the lambda. The implementation only checks that it’s a property. But it’s way better than a pure string.
You could extend the implementation to other event-types quite easy. For example for the INotifyPropertyChanging-interface. The source is attached to this post. Have fun with it.
Implementation: NotifyExtensions.cs, TestNotifyExtensions.cs
- Doctor Who 2005 Season 2 *Spoilers*
- db4o: Transparent-Persistence