【问题标题】:INotifyPropertyChanged and propertyNameINotifyPropertyChanged 和 propertyName
【发布时间】:2016-10-20 19:37:37
【问题描述】:

在实现INotifyPropertyChanged 时,我一直不确定propertyName 的含义。所以通常你将INotifyPropertyChanged 实现为:

public class Data : INotifyPropertyChanged {
   public event PropertyChangedEventHandler PropertyChanged;

   private void NotifyPropertyChanged(string propertyName = "") {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

   private string itsID;
   public string ID { 
             get { return itsID; }
             set { 
                   if (itsID != value) {
                     itsID = value; 
                     NotifyPropertyChanged("ID");
                  }
   }
}

我一直不确定 NotifyPropertyChanged(string propertyName)propertyName 参数。

  1. 可以是任意字符串(如上例中的“MyID”)吗?
  2. 或者.NET 是否使用反射将其与类中的属性对齐,因此它必须与属性名称完全匹配?
  3. 如果propertyNameProperty 的名称不完全匹配,.NET 是否会将整个对象视为changed

【问题讨论】:

  • 只是一个安全提示:当你在做if (PropertyChanged != null) 时,尽量避免这种情况,因为在null 之后检查PropertyChanged 可能确实又是null。相反,更安全/更好的做法是先设置一个局部变量,然后再检查。例如var handler = PropertyChanged; if (handler != null) { handler()... // raise } - 或者从 C#6 开始,您可以使用新的“空条件运算符”:PropertyChanged?.Invoke(...) 兼作 null 检查 一次调用。
  • 这里解释得很好 (cs.colorado.edu/~kena/classes/5448/f12/presentation-materials/…),我认为这是执行所有这些实际跟踪的 .NET 源代码 (referencesource.microsoft.com/#System.Data.Services.Client/…)。 WPF 基本上订阅属性更改事件,然后使用事件参数,其中之一是您用于 ID 的字符串,例如MyID,然后使用它来对控件进行更新。跨度>

标签: c# .net inotifypropertychanged


【解决方案1】:

它本身不是 .NET Framework 本身,它几乎是每个PropertyChanged 订阅者(其中一些确实恰好作为框架的一部分分发)假设您按预期使用接口,通过发送属性名称。如果您发送属性MyID 已更改的通知,当另一个组件查看属性ID 时,它通常会看到通知,比较名称,并得出结论“此通知不适合我”。

【讨论】:

    【解决方案2】:

    如果您想完全匹配属性的名称,您可以使用名为nameof 的新 C#6 功能。 nameof 功能可以回答您所有的问题,因为我们可以说使用nameof 的主要优势是重构。根据您的问题,“重构”是您正在寻找的词:

    NotifyPropertyChanged(nameof(ID));
    

    例如重命名 ID 也会更改属性的名称,否则会破坏编译,但以下内容不会:

    NotifyPropertyChanged("ID")
    

    【讨论】:

    • C# 6 并没有增加太多内容:C# 5 已经提供了 [CallerMemberName] 属性。 NotifyPropertyChanged(); 留出更少的错别字空间。也就是说,这应该是一个评论,它不会试图回答这个问题。
    • @hvd 是的。但对我来说,nameof 的最大用例是使用 INotifyPropertyChanged 接口时。
    • @hvd 实际上,这确实增加了很多。您现在可以更有效地链接数据。使用nameof 时只需右键单击并查找所有引用。比这个CallerMemberName好多了。
    • @Alexandru nameof 当然有它的用途,但我们在这里讨论的是属性设置器内部的引用。您已经发现没有任何 IDE 功能。
    • @hvd 是的,但是NotifyPropertyChanged 的情况也存在于属性设置器本身之外,nameof 可以为开发人员处理。它只是少了一些担心,多了一些组织,这就是我喜欢的。
    【解决方案3】:

    它必须与属性的名称完全匹配。附带说明一下,您应该在调用 PropertyChanged 之前检查该值是否已实际更改,因为这是一个相对昂贵的调用(WPF 不会知道该属性没有更改)。在VS2015中,还可以使用nameof操作符。

    【讨论】:

    • 如果不匹配会怎样?
    • @Denis,UI 不会更新。绑定是按名称的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多