无需重复编写Setter触发代码,实现跨对象监听设备字段变更
解决C#设备监控模块中手动触发状态变更的重复代码问题
我来帮你搞定这个烦人的重复代码问题!你现在每个设备类的Setter都要手动敲OnStateChanged,不仅啰嗦还容易漏写,下面两种成熟方案能彻底帮你摆脱这个麻烦:
方案1:抽象基类封装通知逻辑
最直观的方式是把属性变更通知的逻辑抽离到一个抽象基类里,所有设备类继承这个基类,就能自动触发状态变更,不用再重复写触发代码。
步骤1:实现抽象基类
using System.ComponentModel; using System.Runtime.CompilerServices; using System.Collections.Generic; public abstract class ObservableDeviceBase : IDevice, INotifyPropertyChanged { // 实现IDevice要求的核心属性,用统一方法处理变更 private string _name; public string Name { get => _name; set => SetProperty(ref _name, value); } private string _firmwareVersion; public string FirmwareVersion { get => _firmwareVersion; set => SetProperty(ref _firmwareVersion, value); } // 通用属性变更处理方法:自动对比值、更新字段、触发通知 protected void SetProperty<T>(ref T backingField, T value, [CallerMemberName] string propertyName = null) { if (!EqualityComparer<T>.Default.Equals(backingField, value)) { backingField = value; OnPropertyChanged(propertyName); // 触发你原有的StateChanged事件,也可以让MonitoringModule直接订阅PropertyChanged OnStateChanged(); } } // INotifyPropertyChanged接口实现(可选,用于更精细的属性变更监听) public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } // 保留你原有的StateChanged事件(兼容现有MonitoringModule逻辑) public event Action StateChanged; protected virtual void OnStateChanged() { StateChanged?.Invoke(); } }
步骤2:设备类继承基类
现在你的设备类只需要定义业务属性,不用再手动写触发逻辑:
public class TemperatureSensor : ObservableDeviceBase { private double _temperature; public double Temperature { get => _temperature; set => SetProperty(ref _temperature, value); // 自动触发状态变更 } }
方案2:用Fody.PropertyChanged实现编译时自动注入
如果想彻底摆脱手写Setter的麻烦,可以用Fody的PropertyChanged插件——它会在编译阶段自动给属性注入变更通知代码,连基类都不用写。
步骤1:安装依赖
通过NuGet安装Fody和PropertyChanged.Fody两个包。
步骤2:配置Fody
在项目根目录添加FodyWeavers.xml文件:
<Weavers> <PropertyChanged /> </Weavers>
步骤3:编写设备类
给类标记[AddINotifyPropertyChangedInterface]属性,Fody会自动帮你生成所有通知逻辑:
using PropertyChanged; [AddINotifyPropertyChangedInterface] public class PressureSensor : IDevice { // 自动生成带变更通知的Setter,完全不用手写逻辑 public string Name { get; set; } public string FirmwareVersion { get; set; } public double Pressure { get; set; } // 保留原有的StateChanged事件,通过订阅自动生成的PropertyChanged触发 public event Action StateChanged; // Fody会自动生成PropertyChanged事件,我们在这里绑定StateChanged触发逻辑 private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { StateChanged?.Invoke(); } }
后续调整MonitoringModule
两种方案都支持两种监听方式:
- 继续使用原有的
StateChanged事件(兼容现有代码) - 改用
PropertyChanged事件(能获取具体变更的属性名,灵活性更高)
内容的提问来源于stack exchange,提问作者Ciphra
相关产品推荐
相关产品推荐

