c# - 实现 INotifyPropertyChanged - 是否存在更好的方法?

标签 c# .net winforms inotifypropertychanged

Microsoft 应该为 INotifyPropertyChanged 实现一些活泼的东西,就像在自动属性中一样,只需指定 {get;放;通知; 我认为这样做很有意义。或者有什么并发症吗?

我们自己能否在我们的属性中实现类似“通知”的功能。是否有用于在您的类中实现 INotifyPropertyChanged 的优雅解决方案,或者唯一的方法是在每个属性中引发 PropertyChanged 事件。

如果不能,我们可以编写一些东西来自动生成代码片段以引发 PropertyChanged 事件吗?

最佳答案

不使用像 postsharp 这样的东西,我使用的最小版本使用像这样的东西:

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

每个属性就像这样:

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

不是很大;如果需要,它也可以用作基类。 SetField 返回的 bool 会告诉您它是否是空操作,以防您想要应用其他逻辑。


或者使用 C# 5 更容易:

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

可以这样调用:

set { SetField(ref name, value); }

编译器将自动添加 "Name"


C# 6.0 使实现更容易:

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

...现在使用 C#7:

protected void OnPropertyChanged(string propertyName)
   => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

protected bool SetField<T>(ref T field, T value,[CallerMemberName] string propertyName =  null)
{
    if (EqualityComparer<T>.Default.Equals(field, value)) return false;
    field = value;
    OnPropertyChanged(propertyName);
    return true;
}

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

并且,对于 C# 8 和 Nullable 引用类型,它看起来像这样:

public event PropertyChangedEventHandler? PropertyChanged;

protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = "")
{
    if (EqualityComparer<T>.Default.Equals(field, value)) return false;
    field = value;
    OnPropertyChanged(propertyName);
    return true;
}

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

关于c# - 实现 INotifyPropertyChanged - 是否存在更好的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1315621/

相关文章:

C#结合MSIL——JIT跳过验证

c# - 正则表达式停止除 _ 之外的特殊字符 not in start

c# - Cursor.Current 与 this.Cursor

c# - WPF ItemsControl 和 WrapPanel 走进酒吧

c# - XNA:调整正交窗口大小而不拉伸(stretch)

c# - 如何知道重定向 URL

c# - 如何检查程序集 (dll) 的版本?

.net - AES 256 加密

c# - 为 ListView Items_added 添加事件处理程序

c# - 随机值似乎不是真的随机?