当实现INotifyPropertyChanged接口时,C#中的[NotifyPropertyChangedInvocator]是什么?

52

我看到了两种INotifyPropertyChanged的实现方式。

  • 第一种:

    public abstract class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    
  • 第二个:

  • public abstract class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

在第二个方法中,您会看到一个额外的属性 [NotifyPropertyChangedInvocator] 在方法 OnPropertyChanged 上。

在我的情况下,两者行为相同,但是何时、为什么以及如何使用这个 [NotifyPropertyChangedInvocator] 属性?使用它有什么好处?我在互联网上搜索了很多,但没有找到什么好的答案。

2个回答

93
这是Resharper的Annotations属性,旨在在您的代码看起来可疑时发出警告 :)
考虑以下内容:
public class Foo : INotifyPropertyChanged 
{
     public event PropertyChangedEventHandler PropertyChanged;
     
     [NotifyPropertyChangedInvocator]
     protected virtual void NotifyChanged(string propertyName) { ... }
  
     private string _name;
     public string Name {
       get { return _name; }
       set { 
             _name = value; 
             NotifyChanged("LastName");//<-- warning here
           } 
     }
   }

使用[NotifyPropertyChangedInvocator]属性,在NotifyChanged方法上Resharper会提醒你,你正在用(可能)错误的值调用该方法。

因为Resharper现在知道应该调用哪个方法来进行更改通知,它将帮助你将普通属性转换为具有更改通知的属性: Visual Studio Screenshot showing ReShaper suggestions
转换成这样:

public string Name
{
  get { return _name; }
  set
  {
    if (value == _name) return;
    _name = value;
    NotifyChange("Name");
  }
}

这个例子来自于此处关于[NotifyPropertyChangedInvocator]属性的文档:
enter image description here

13
加1分给解释,而不是只回答一个链接。这应该被选为答案。 - user3791372
我不明白。是什么警告,为什么,何时,为什么?从“LastName”变成“Name”是正常的吗?我很困惑。(链接现在已失效 - 页面也不在archive.org上) - jeromej
@JeromeJ 我已经更新了链接。这个警告是resharper的功能(用“zigzag”蓝色下划线标记代码)。要了解上述属性为什么有问题的更多信息,请搜索“INotifyPropertyChanged”以及通常如何实现它的示例。 - Jens Kloster
如果您有多个带有此标记的方法,ReSharper将在上下文菜单中列出它们,并让您选择要自动实现的方法(例如使用string或使用Expression<Func<T>>的方法)。 - jeromej

5

这是C#的一个特性。Resharper只是一个工具,不能添加任何C#不支持的额外代码。NotifyPropertyChangedInvocator背后也有一些东西。 - Waqas Idrees
5
@WaqasIdrees,您可以发布NotifyPropertyChangedInvocator的链接或文档,以证明它是C#配套的。 - Sajeetharan
3
对于剽窃,+0, -1 - Sriram Sakthivel
@WaqasIdrees - INotifyPropertyChanged 是在 .NET 库中定义的(它不是 C# 语言特性)。NotifyPropertyChangedInvocator 是 ReSharper 的一个功能。在 MSDN 上搜索“NotifyPropertyChangedInvocator”(http://social.msdn.microsoft.com/Search/en-US?query=NotifyPropertyChangedInvocator),你会发现没有关于它的文档,只有指向论坛和 Stackoverflow 的链接。 - Richard Szalay
1
仅仅声称您可以从代码中删除NotifyPropertyChangedInvocator以使其正常工作,并不能真正回答这个问题。 - ProfK
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接