【问题标题】:Should I raise INotifyPropertyChanged when the value changes or when set has been called? [closed]当值更改或调用 set 时,我应该提高 INotifyPropertyChanged 吗? [关闭]
【发布时间】:2017-02-17 06:35:19
【问题描述】:

在实现INotifyPropertyChanged时,应该只在n != value时调用PropertyChanged,还是应该因为set被调用才调用?

我在这里寻找的是行业标准建议(如果存在这样的东西),哪些实施更好以及为什么。

示例 1 - 说明了一个“愚蠢”的事件引发策略

class Person : INotifyPropertyChanged
{
    private string name;

    public event PropertyChangedEventHandler PropertyChanged;

    public string Name
    {
        get
        {
            return name;
        }

        set
        {
            name = value;
            PropertyChanged(this, new PropertyChangedEventArgs(nameof(Name)));
        }
    }
}

示例 1 的用例

Person p = new Person();

p.Name = "John"; // ProperyChanged fired
p.Name = "John"; // ProperyChanged fired

示例 2 - 说明了一个“聪明”的事件引发策略

class Person : INotifyPropertyChanged
{
    private string name;

    public event PropertyChangedEventHandler PropertyChanged;

    public string Name
    {
        get
        {
            return name;
        }

        set
        {
            if(name != value)
            {
                name = value;
                PropertyChanged(this, new PropertyChangedEventArgs(nameof(Name)));
            }
        }
    }
}

示例 2 的用例

Person p = new Person();

p.Name = "John"; // ProperyChanged fired
p.Name = "John"; // ProperyChanged ignored as name == value

注意示例 2 中的 if(name != value),它只允许更改值,以及当传入值与现有值不匹配时的 ProperyChanged 事件。

【问题讨论】:

  • 这就是编码的伟大之处:你可以让它做任何你想做的事情。
  • 我认为这可能是那些“视情况而定”的答案之一。
  • 我只是想知道两者之间是否有“推荐”的方法,为什么?
  • 您已经列出了两个选项和第二个版本的优点。这完全取决于您的用例。您很可能想要获取每个事件,就像您可能只想要真正的更改一样。
  • @JeroenVannevel 我知道这是一个“取决于”的答案。我只是从性能的角度想知道,因为示例 1 似乎如果对象被频繁击中可能会变得有点贵。

标签: c# inotifypropertychanged


【解决方案1】:

顾名思义,INotifyPropertyChanged,根据msdn:

INotifyPropertyChanged 接口用于通知客户端(通常是绑定客户端)属性值已更改。

最好只在值发生变化时触发事件。

https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx

典型的实现模式是这样的:

public string Foo
{
    get { return _foo; }
    set
    {    
        if (string.Equals(_foo, value)) return;

        _foo= value;
        OnPropertyChanged();
    }
}

顺便说一下,这也是 ReSharper 的约定,可以在这里找到; https://www.jetbrains.com/help/resharper/2016.1/Coding_Assistance__INotifyPropertyChanged_Support.html

附带说明:仅在更改的值上触发将保护您在更新从其他值计算的值时免受循环依赖。

示例: 考虑以下代码:

public string DependentFoo
{
    get { return _foo; }
    set
    {    
        if (string.Equals(_foo, value)) return;

        _foo= value;

        //if some condition:
        DependentBar = "";
        OnPropertyChanged();
    }
}

public string DependentBar
{
    get { return _bar; }
    set
    {    
        if (string.Equals(_bar, value)) return;

        _bar = value;

        //if some condition:
        DependentFoo = "";
        OnPropertyChanged();
    }
}

虽然这不是一个很好的例子,但我想你会明白的。

【讨论】:

    【解决方案2】:

    documentation of INotifyPropertyChanged 表示接口的用途是

    通知客户端属性值已更改。

    这显然是指“财产价值”的变化。文档页面上的示例也使用示例 2 中的模式。

    【讨论】:

      【解决方案3】:

      没有“正确”的做法。这一切都取决于你需要它做什么。 例如:

      如果您只需要更新 GUI,那么我会说在属性实际上没有更改时调用 PropertyChanged 是不必要的。但是,如果您想将该事件用于其他目的(例如日志记录或类似的东西),那么它绝对是一个解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-11
        • 2010-10-08
        • 2013-06-18
        • 1970-01-01
        • 2016-08-31
        • 2014-07-10
        • 1970-01-01
        • 2013-08-05
        相关资源
        最近更新 更多