C#和属性更改通知

本文关键字:通知 属性 | 更新日期: 2023-09-27 17:59:01

为什么C#让我这么做:

public class SomeClass {
    public event PropertyChangedEventHandler Changed;
    public void OnChanged(object sender, PropertyChangedEventArgs e)
    {
        if (Changed != null)
            Changed(sender, e);
    }
    [XmlIgnore]
    private string _name;
    public string Name { 
        get { return _name; } 
        set 
        { 
            _name = value; 
            OnChanged(this, new PropertyChangedEventArgs("Name")); 
        }
    }
}

像这样的东西的内部:

[GeneratesChangeNotifications]
public class SomeClass {
    [GeneratesChangeNotification] 
    public string Name { get; set; }
}  

我知道你可以通过PostSharp和其他第三方图书馆做到这一点。。。但是,我认为,应该在语言中嵌入一些完整的、容易出错的东西(例如,拼写字符串中的名称)。。。为什么微软不这么做?。。。有没有纯粹的语言原因导致这种情况没有发生。这是一种常见的需求。

C#和属性更改通知

到目前为止,这里是我想出的最好的。。。我已经编写了一个名为NotifyPropertyChanged的类。。。它处理属性名称、是否更改的测试、本地变量的更新以及更改通知。。。而SetProperty函数是通用的,因此一个函数可以处理所有类型的属性。。。效果很好。

(请注意,如果您愿意,可以使用多个属性名称调用OnPropertyChanged。)

public class NotifyPropertyChanged : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(params string[] props)
    {
        foreach (var prop in props)
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
    }
    public bool SetProperty<T>(ref T oldValue, T newValue, [CallerMemberName]string prop = "")
    {
        if (oldValue == null && newValue == null)
            return false;
        if (oldValue != null && oldValue.Equals(newValue))
            return false;
        oldValue = newValue;
        OnPropertyChanged(prop);
        return true;
    }
}

然后这样使用:

public class MyClass : NotifyPropertyChanged
{
    public string Text { get => _text; set => SetProperty(ref _text, value); }
    string _text;
}

My RaisePropertyChanged始终使用调用方成员名称,或者在需要时反映表达式中传入的属性名称(即,如果我需要使一个属性通知另一个属性)。您不能总是保证所有属性都可以通知,因此能够一次通知多个属性是非常有用的。

此外,对于标准模型,使用事件允许任何人订阅,而属性模型则不能订阅。