Parts 1 & 2 of this unintended trilogy:
My previous post elicited a couple of good comments.
Matt noted that my use of reflection to get the property name could be a problem in due to inlining in Release mode:
Jérôme and Mark suggested that an Expression might be a better solution than reflection. Here's what that could look like:
My shared method to update property backing variables and raise the INotifyPropertyChanged.PropertyChanged event:
protected bool CheckForPropertyChange<T>(T value, ref T currentValue, Expression<Func<T>> expr)
{
if (value.Equals(currentValue)) return false;
currentValue = value;
if (PropertyChanged != null)
{
var body = expr.Body as MemberExpression;
if (body != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(body.Member.Name));
}
}
return true;
}
...and properties using it:
private string _CustomerName;
public string CustomerName
{
get { return _CustomerName; }
set { CheckForPropertyChange(value, ref _CustomerName, ()=> CustomerName); }
}
private string _PhoneNumber;
public string PhoneNumber
{
get { return _PhoneNumber; }
set { CheckForPropertyChange(value, ref _PhoneNumber, () => PhoneNumber); }
}
Using the lambda (e.g. "() => CustomerName") to specify the property name is an improvement over a hardcoded string because the compiler validates it and it's "refactorable". As Jérôme pointed out on his blog, the lambda is not actually called, just used by the CheckForPropertyChange method to determine the property name.