在实现INotifyPropertyChanged的类中,我经常会看到这种模式:
public string FirstName
{
get { return _customer.FirstName; }
set
{
if (value == _customer.FirstName)
return;
_customer.FirstName = value;
base.OnPropertyChanged("FirstName");
}
}
准确地说是行
if (value == _customer.FirstName)
return;
困扰着我。我经常这样做,但我不确定它是否需要也不好。毕竟,如果一个调用者分配了相同的值,我不想重新分配该字段,特别是,通知我的订阅者该属性已经改变,从语义上来说它没有。
除了通过释放UI来更新屏幕上看起来相同的内容/ whatever_medium而保存一些CPU / RAM /等,我们获得了什么?
有些人可以通过在属性上重新分配相同的值来强制刷新(不过这会是一个很好的做法)吗?
1。我们应该这样做还是不应该这样做?
2。为什么?
答案 0 :(得分:10)
是的,当消费者设置的属性值等于已经持久的值时,应立即返回。
首先,没有理由在属性的设置者中浪费任何时间或资源 - 该值已经设置,因此不需要进一步的操作。如果存储在属性的支持字段中的值未更改,则永远不应该调用OnPropertyChanged
- 当值已更改而不是属性的setter已被更改时,该方法将被引发调用。
然而,所有这一切 - 如果设定者没有打电话给OnPropertyChanged
,我就不会费心去检查价值。如果是一个简单的setter,它只设置了后备字段的值而没有别的,那么总是设置值而不是先检查然后设置值会更快。仅当属性的setter具有不应触发的额外逻辑或可能导致不必要的性能损失时才使用此模式。
答案 1 :(得分:7)
或者你可以这样做:
set
{
if (value != _customer.FirstName)
{
_customer.FirstName = value;
base.OnPropertyChanged("FirstName");
}
}
不需要多个返回路径。
为了进一步回答你的问题,我不会强制更新属性,如果它被相同的值覆盖。真的没有意义,因为你可能不会从中获得任何好处。 (我可以看到每次有人试图更新值时你想要跟踪的实例。)
答案 2 :(得分:2)
反对该模式的唯一参数(如果值没有改变则返回)我可以想到的是纯粹主义者的观点,即每个函数应该只有一个出口。不是纯粹主义者,我不同意。如果值没有改变,我发现没有错误,避免了通知更新。
答案 3 :(得分:1)
不应使用它的唯一情况是,当您知道可以在类上拥有脏数据时,例如在可能的ORM层对象上由于另一个用户的修改,与底层数据库相比,它们已经过时了。
如果这种情况不影响你,那就赶快离开!
<子>修改子>
我误解了你的问题,因为你在谈论 setters ,而不是 getters 。
类似的点适用。如果设定的操作是昂贵的,并且不应该有任何副作用(它不应该!对设置者的副作用是<blink>
邪恶 </blink>
!! 1),那么这是一个有效的优化。
答案 4 :(得分:1)
我想,不能提早返回的一个原因是订阅者迟到了。他们可能不知道对象的当前状态,如果您提前返回,他们将错过设置者通知。
答案 5 :(得分:0)
大多数情况下,这些属性用于绑定。但是,一旦您自己开始使用NotifyPropertyChanged
事件(在自己的标记扩展,行为,MVVM中的VM之间,等等),您就会意识到您只是希望此事件始终发生。
对我来说,此检查(通知保护)是一种过早的优化。我经常以""
为propertyName
的形式来提高事件质量,只是刷新绑定或强制某些自定义内容的事件,仅此一项的代价就更高了。
我认为不需要保护每个财产。为什么?从什么样的操作?动画在依赖项属性上运行。用户更新(当视图绑定更新源时)总是很慢。对于任何更新,都是从您背后的代码内引发的需要事件。
对我来说,它看起来像是一种模式,是无缘无故地发明并盲目遵循的。当然,在某些情况下,您需要防止在某些情况下运行属性设置程序代码。如果您添加了此类检查以解决某些性能问题,那也没关系。但不是提前。