实施INotifyPropertyChanged的 - 没有更好的方法存在吗?存在、方法、INotifyPropertyChanged

2023-09-02 01:16:27 作者:分手后的思念叫犯贱

微软应该已经实施了一些活泼的 INotifyPropertyChanged的,像在自动属性,只需指定 {获得;组;通知;} 我认为它使一个很大的意义做到这一点。还是有什么并发症办呢?

Microsoft should have implemented something snappy for INotifyPropertyChanged, like in the automatic properties, just specify {get; set; notify;} I think it makes a lot of sense to do it. Or are there any complications to do it?

我们可以自己实现像我们的性质通知。有没有实现一个优雅的解决方案 INotifyPropertyChanged的 在你的类或做的是通过提高的PropertyChanged 事件每个属性。

Can we ourselves implement something like 'notify' in our properties. Is there a graceful solution for implementing INotifyPropertyChanged in your class or the only way to do it is by raising the PropertyChanged event in each property.

如果不是我们可以写一些东西来自动生成一张code,以提高的PropertyChanged 事件?

If not can we write something to auto-generate the piece of code to raise PropertyChanged event?

推荐答案

在不使用类似postsharp,我用的是最小的版本使用类似:

Without using something like postsharp, the minimal version I use uses something like:

public class Data : INotifyPropertyChanged
{
    // boiler-plate
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    protected bool SetField<T>(ref T field, T value, string propertyName)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    // props
    private string name;
    public string Name
    {
        get { return name; }
        set { SetField(ref name, value, "Name"); }
    }
}

每个属性然后只是这样的:

Each property is then just something like:

    private string name;
    public string Name
    {
        get { return name; }
        set { SetField(ref name, value, "Name"); }
    }

这是不是巨大的;它也可以,如果你想用作基类。该布尔返回从 SetField 告诉你,如果它是一个空操作,如果你想申请其他逻辑。

which isn't huge; it can also be used as a base-class if you want. The bool return from SetField tells you if it was a no-op, in case you want to apply other logic.

或更容易用C#5:

protected bool SetField<T>(ref T field, T value,
    [CallerMemberName] string propertyName = null)
{...}

set { SetField(ref name, value); }

与编译器将添加名称自动。

C#6.0使得执行简单:

C# 6.0 makes the implementation easier:

protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}