如果值与当前属性相同,INotifyPropertyChanged标准实现是否包含no-op ?

本文关键字:实现 标准 INotifyPropertyChanged 是否 包含 no-op 属性 如果 | 更新日期: 2023-09-27 17:54:05

在代码审查期间,建议按如下方式实现我的INotifyPropertyChanged:

public string Prop
{
  get{return _prop;}
  set
  {
    if(_prop == value) return;
    _prop = value;
    OnPropertyChanged(()=>Prop);
  }
} 

这一行是:

if(_prop == value) return;

我的问题是这是否真的有必要?我刚刚遇到了这样一种情况,即如果组合框返回相同的引用,则框架忽略了OnPropertyChanged(我不确定这是否全面正确,但是?)。

我个人不认为有必要添加额外的代码混乱,如果它真的没有什么不同。INotifyPropertyChanged的框架实现是否使if (_prop == value) return;变得无关紧要或多余?暂且不谈框架隐含的事件,这种微优化是否可以作为一个起点?

如果值与当前属性相同,INotifyPropertyChanged标准实现是否包含no-op ?

通常,接口是具有语义意义而非纯粹技术意义的契约。在INotifyPropertyChanged的情况下,语义含义就像它听起来的那样——当属性发生变化时,实现该接口的对象会通知您。

"改变"这个词是关键。是的,许多订阅INotifyPropertyChanged事件的类可能会以这样一种方式编写,即它们将"新"值与之前的值进行比较,如果它实际上没有改变,它们就不做任何事情。但是,这不是您应该依赖的东西-如果您在属性没有更改时触发事件,则是您的代码不正确。

如果客户端代码执行自己的检查,以确定值是否已经更改,这是他们非常谨慎,但他们不需要这样做,也不应该期望他们这样做。

简短版本:是的,在你的INotifyPropertyChanged实现中做检查。不要指望客户端代码为您执行检查

我认为没有必要。通常在不想更新属性时这样做当值等于旧的属性时。在这种情况下,我这样做:

public string Prop
{
  get
  {
      return _prop;
  }
  set
  {
      if (_prop != value) 
      {
          _prop = value;
          OnPropertyChanged(()=>Prop);
      }
   }   
} 

没有标准的 INotifyPropertyChanged实现,尽管大多数人/框架在基类中与您提到的方法一起实现它(使用带有属性名的表达式触发PropertyChanged事件)。

您没有提到OnPropertyChanged方法的来源(或显示实现),但通常使用if (_prop == value) return;来避免触发PropertyChanged事件,如果新值与旧值相同。

大多数人会认为这是一个微优化,不需要,但如果你有一个热路径,其中的值会非常频繁地变化,或者如果触发它会做很多工作,这可能是一个好主意。那么你可能又遇到另一个问题了:P

在这种情况下,我发现很难相信该方法可以阻止事件被触发,因为它不知道新的值。某些特定控件可能忽略基于事件的更新的原因可能是它们正在比较侦听端的值,但是您的ViewModel无法保证是这种情况。