不使用私有字段如何触发属性的INotifyPropertyChanged变更通知?
要在保留属性变更通知功能的前提下移除冗余的私有字段,有两种成熟的实现方案:
方案1:基类封装字典存储属性值(无任何私有字段要求)
这种方案不需要每个属性单独定义私有字段,所有属性值统一存储在基类的字典中,运行时自动匹配属性名读写值。
第一步:实现通用基类
using System.Collections.Generic; using System.ComponentModel; using System.Runtime.CompilerServices; public class ObservableBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private readonly Dictionary<string, object> _propertyStore = new(); protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } protected T GetValue<T>([CallerMemberName] string propertyName = null) { return _propertyStore.TryGetValue(propertyName, out var value) ? (T)value : default; } protected bool SetValue<T>(T newValue, [CallerMemberName] string propertyName = null) { var oldValue = GetValue<T>(propertyName); if (EqualityComparer<T>.Default.Equals(oldValue, newValue)) return false; _propertyStore[propertyName] = newValue; OnPropertyChanged(propertyName); return true; } }
第二步:改写业务属性
业务类继承上述基类后,属性可以直接写为以下形式,完全不需要定义私有字段:
public class YourBusinessClass : ObservableBase { /// <summary> /// target system /// </summary> public string DestSystem { get => GetValue<string>(); set => SetValue(value); } }
注:借助[CallerMemberName]特性,不需要手动传入属性名,功能和原写法完全一致,变更通知会正常触发。
方案2:使用CommunityToolkit.Mvvm源生成器(性能最优)
这是微软官方推荐的MVVM工具包方案,编译时会自动生成后台字段和属性变更逻辑,减少手写代码量,性能和手动写字段完全一致。
操作步骤:
- 安装NuGet包
CommunityToolkit.Mvvm - 业务类声明为
partial,并继承ObservableObject - 用
[ObservableProperty]特性标注需要生成属性的字段,编译时会自动生成对应的公共属性和变更通知逻辑
using CommunityToolkit.Mvvm.ComponentModel; public partial class YourBusinessClass : ObservableObject { /// <summary> /// target system /// </summary> [ObservableProperty] private string _destSystem; }
注:这种方案的私有字段仅作为源生成器的标记,不需要你手动写get/set逻辑,编译后生成的公共DestSystem属性功能和原写法完全一致。如果要求完全不出现私有字段,推荐选择方案1。
内容的提问来源于stack exchange,提问作者Ryu
相关产品推荐
相关产品推荐

