You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需重复编写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

两种方案都支持两种监听方式:

  1. 继续使用原有的StateChanged事件(兼容现有代码)
  2. 改用PropertyChanged事件(能获取具体变更的属性名,灵活性更高)

内容的提问来源于stack exchange,提问作者Ciphra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:46:35