PropertyChanged(“Implementation”)
As I expected (I saw many debates on INotifyPropertyChanged on the web) I got some reactions to my previous post and one of them by Willem who pointed out a construction that I forgot to mention and is very elegant.
Instead of using reflection we can also use Linq expressions to refer to methods and properties and this allows us to make the following construction:
public class Person : INotifyPropertyChanged
{
#region FirstName Property
private string _firstName;
public string FirstName
{
get
{
return _firstName;
}
set
{
if (_firstName != value)
{
_firstName = value;
NotifyPropertyChanged(x => x.FirstName);
}
}
}
#endregion
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged<TProperty>(
Expression<Func<Person, TProperty>> propertyExpression)
{
MemberExpression memberExpression = propertyExpression.Body
as System.Linq.Expressions.MemberExpression;
if (memberExpression == null || (memberExpression != null &&
memberExpression.Member.MemberType != MemberTypes.Property))
{
throw new ArgumentException(
"The specified expression does not represent a valid property");
}
OnPropertyChanged(memberExpression.Member.Name);
}
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler p = PropertyChanged;
if (p != null)
{
p(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
Things to note:
- Full renaming support without needing to remember to update the string.
- A slight performance penalty but better than reflection (a good place to get up to speed with .
You could put these in a base class but I want to be able to pick any base class I want so I made a new template and a new snippet. Download them here.
Copy the snippet to: <drive>:Users<user>DocumentsVisual Studio 2010Code SnippetsVisual C#My Code Snippets
Copy the zipped template to: <drive>:Users<user>DocumentsVisual Studio 2010TemplatesItemTemplatesVisual C#