2010-04-12 70 views
11

在实现INotifyPropertyChanged的类我常常看到这样的图案:如果指定相同的值,setter是否应立即返回?

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更新屏幕上可能看起来相同的东西来保存一些CPU/RAM/etc/whatever_medium我们获得了什么?

有人可以通过重新分配物业上的相同价值来刷新刷新状态吗?(但不是这种做法是好的做法)?

1.我们应该做还是不应该?

2.为什么?

回答

9

是的,当消费者设置的属性值等于已经保存的值时,应该立即返回。

首先,没有理由浪费任何时间或资源在财产的制定者 - 价值已经设定,因此不需要进一步的行动。如果存储在属性背景字段中的值未发生更改,则您不应该调用OnPropertyChanged - 如果该值已更改而不是调用该属性的setter时,则会引发该方法。

然而所有这些 - 如果制定者没有拨打OnPropertyChanged,我就不会费心检查数值。在一个简单的设置器中,只设置了后台字段的值,而没有其他设置,实际上,设置值始终会更快,而不是首先检查值,然后设置值。只有当属性的设置者有额外的逻辑,不应该触发或可能会导致不必要的性能损失时,才使用此模式。

+2

我想我会不同意你的#2是真的。取决于正在做的事情。比较两个字符串比设置字符串的引用昂贵得多。即使它们不同,你也总是添加处理。 – galford13x 2010-04-12 16:51:31

+0

要添加到我的上一个语句中,根据意图调用OnPropertyChanged可能仍然是需要的。有时候,即使值没有改变,您可能也想要输入OnPropertyChanged事件,只是因为输入了该值。 – galford13x 2010-04-12 16:54:41

2

反对该模式的唯一参数(如果值没有改变,则返回)我能想到的是纯粹者认为每个函数只应该有一个出口。不是纯粹主义者,我不同意。如果数值没有改变,我发现没有什么问题,避免通知更新。

+3

我从来没有被*每个函数/方法*点的退出路径所证实。 – voyager 2010-04-12 16:47:30

+0

我个人遇到太多场景,不能将每个函数限制为单个退出路径,而没有不必要地将其分割成多个函数,即使如此也不总是可以避免的,而不会混淆代码(如果函数的一半以上在'else'块内,恕我直言,你做错了)。 – 2016-09-05 05:39:32

7

或者你可以这样做:

set 
    { 
     if (value != _customer.FirstName) 
     { 

      _customer.FirstName = value; 

      base.OnPropertyChanged("FirstName"); 
     } 
    } 

无需多次返回路径。

为了进一步回答你的问题,如果它被相同的值覆盖,我不会强制更新属性。这实在没有意义,因为你可能不会从中受益。 (我可以看到每次有人尝试更新值时想要跟踪的实例。)

+0

无论如何,我认为他所要求的并不是确切的代码路径,而是应该避免在重复设置上执行setter代码。 (像'PUT'一样工作,不像你的web开发人员用'POST'。) – voyager 2010-04-12 16:56:01

+3

无需增加嵌套。 :) – ANeves 2010-04-12 17:14:52

+0

实际上,很多人认为你不应该在if语句中忽略{}:if(..){return;}。仍然嵌套,并且您有多个返回路径。 – kemiller2002 2010-04-12 17:31:47

1

当你不应使用它是当你知道你可以在你的类数据,例如一个ORM层对象上相比于基础数据库中可能有过时的值的唯一情况因为其他用户的修改。

如果这种情况不会影响你,那就缓存吧!


编辑

我误解你的问题,因为你是在谈论制定者,不干将

类似积分适用。如果设置操作是一个昂贵的,并且不应该有任何一种副作用(它不应该!)对setter的副作用是<blink>邪恶 !! 1),那么这是一个有效的优化。

1

我想,早点回来的一个原因是晚入伍的用户。他们可能不知道对象的当前状态,并且如果您提前返回,将错过设置者通知。

+1

迟到的加入者在加入时提供当前值或者不相关:如果他们这样做了,他们不需要更新;如果他们不这样做,他们选择忽略它,不需要通知没有发生的变化。无论哪种方式提高事件是无关紧要的。 – ANeves 2010-04-12 17:18:17

+0

@sr,您将重点放在*值*上。我更重视触发价值的*事件*(不是价值不重要,而是次于事件本身)。有一些完全有效的用例,其中一些其他对象只需要知道它发生的值,并且不一定有兴趣知道它订阅之前发生了什么。如果你不能想到这样的用例,让我知道,我会给你几个例子。 – Anurag 2010-04-12 19:16:18

+0

我很欣赏你提出的观点,这与某些应用程序非常相关。我最近不得不修改面向应用属性更改通知的面向方面的解决方案,因为如果值相同,方面总是立即返回。这就是我大部分时间想要的,但是我遇到了一个对事件本身感兴趣的用例,而不是实际的价值。现在我有可以做的任何方面。尽管如此,我可以看到一个观点,即有一个单独的事件可以观察,而不是“在变化中”事件。 – DannyMeister 2013-03-22 16:50:47