通过利用EqualityComparer.Default,您可以将属性设置器代码减少到一行,如下所示:
private int unitsInStock;
public int UnitsInStock
{
get { return unitsInStock; }
set { SetProperty(ref unitsInStock, value, "UnitsInStock"); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void SetProperty<T>(ref T field, T value, string name)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
如果您的视图模型从定义 SetProperty 方法和 PropertyChanged 事件的基类继承,那么在您的子视图模型中支持 INotifyPropertyChanged 所需的代码量将变得非常少(1 行)。
这种方法比其他答案中提到的代码编织方法更冗长,但不需要您修改构建过程来完成它。
一定要看看即将发布的C# 5 Caller Info attributes,看起来它们可以让我们避免在方法中使用魔法字符串,而不会产生反射的性能成本。
更新(2012 年 3 月 1 日):
.NET 4.5 Beta 已经发布,有了它,您可以进一步细化上述代码,从而消除调用者中对字符串文字的需求:
private int unitsInStock;
public int UnitsInStock
{
get { return unitsInStock; }
set
{
SetProperty(ref unitsInStock, value);
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void SetProperty<T>(ref T field, T value, [CallerMemberName] string name = "")
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
我有一个blog post 会更详细地讨论它。