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

不使用私有字段如何触发属性的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 22:51:01