我应该在值更改或调用set时提升INotifyPropertyChanged吗?

时间:2016-10-08 10:13:35

标签: c# inotifypropertychanged

在实施INotifyPropertyChanged时,PropertyChanged只应在n != value时调用,还是应该调用,因为已调用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事件。

3 个答案:

答案 0 :(得分:3)

正如界面名称所示,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

作为旁注:仅在更改的值上激活时,可以在更新从其他值计算的值时保护您免受circulair依赖性的影响。

示例: conider以下代码:

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();
    }
}

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

答案 1 :(得分:2)

documentation of INotifyPropertyChanged表示界面的目的是

  

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

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

答案 2 :(得分:-2)

没有"对"这样做的方式。这一切都取决于你需要它做什么。 例如:

如果你需要的只是更新GUI,那么我说当属性没有改变时调用PropertyChanged是不必要的。但是,如果您希望将该事件用于其他目的(例如日志记录或类似的东西),那么它最有可能成为一种解决方案。