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/