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和其他第三方图书馆做到这一点。。。但是,我认为,应该在语言中嵌入一些完整的、容易出错的东西(例如,拼写字符串中的名称)。。。为什么微软不这么做?。。。有没有纯粹的语言原因导致这种情况没有发生。这是一种常见的需求。
到目前为止,这里是我想出的最好的。。。我已经编写了一个名为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
始终使用调用方成员名称,或者在需要时反映表达式中传入的属性名称(即,如果我需要使一个属性通知另一个属性)。您不能总是保证所有属性都可以通知,因此能够一次通知多个属性是非常有用的。
此外,对于标准模型,使用事件允许任何人订阅,而属性模型则不能订阅。