C#实现INotifyPropertyChanged的优雅封装方案(含简洁写法与自动生成)


 

在使用 WPF、MAUI 或其他基于 MVVM 架构的 C# 框架时,我们常常需要实现 INotifyPropertyChanged 接口,以便属性值变更时通知 UI 更新。但手动编写字段与通知逻辑会带来重复劳动。本文将介绍几种优雅且高效的封装方式,助你告别繁琐代码。

一、经典写法(对比)

 

C# 全选
public class Person : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get => _name;
        set
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged(nameof(Name));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

这种写法虽然可控,但每个属性都要手写 _字段get/set 和通知逻辑,容易出错,维护性较差。

二、推荐封装方案:通用 SetProperty 方法

我们可以创建一个基类,封装常用的 SetProperty 方法,显著减少重复代码:

C# 全选
public abstract class BindableBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool SetProperty<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;
    }

    protected void OnPropertyChanged(string propertyName)
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

使用示例:

C# 全选
public class Person : BindableBase
{
    private string _name;
    public string Name
    {
        get => _name;
        set => SetProperty(ref _name, value);
    }
}

优雅又不失性能,适合大多数中小型项目。

三、极简方案:Fody 自动生成

使用 NuGet 包 Fody.PropertyChanged,可以彻底抛弃 PropertyChanged 手写逻辑:

Install-Package Fody

Install-Package PropertyChanged.Fody

然后只需:

C# 全选
[AddINotifyPropertyChangedInterface]
public class Person
{
    public string Name { get; set; }
}

Fody 会自动编译成带 INotifyPropertyChanged 的完整类,适合喜欢“魔法”的开发者。

四、现代化方案:CommunityToolkit.Mvvm(微软推荐)

这是一个源代码生成器方案,类型安全、性能极高。

Install-Package CommunityToolkit.Mvvm

使用方式:

C# 全选
public partial class Person : ObservableObject
{
    [ObservableProperty]
    private string name;
}

它会自动生成 Name 属性及通知事件,语法优雅,推荐使用在 MAUI、WinUI、WPF 等现代项目中。

 

✨ 总结

封装方式简洁度性能自动化推荐指数
手动实现⭐⭐⭐⭐⭐🔹🔹
SetProperty⭐⭐⭐⭐⭐⭐⭐⭐🔹🔹🔹🔹
Fody⭐⭐⭐⭐⭐⭐⭐✅✅🔹🔹🔹🔹
CommunityToolkit⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐✅✅🔹🔹🔹🔹🔹

选择最适合自己项目体量和团队习惯的方案,能大幅提升开发效率与代码质量。

 

 

版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
张国生
上一篇:如何从Gitblit服务器恢复Git仓库:不需要重新部署
下一篇:LInux Jenkins安装
评论列表

发表评论

评论内容
昵称:
关联文章

C#实现INotifyPropertyChanged优雅封装方案简洁写法自动生成
【.NET 树莓派】MPD Mini-API 封装
C#进化——C#发展史、C#1.0-10.0语法系统性梳理、C#JAVA对比
ManualResetEvent实现线程暂停恢复
C#基础系列-过滤器特性
Roslyn+T4+EnvDTE项目完全自动化(1) ——类自动生成界面
c# IdHelper生成唯一雪花Id
bat脚本:生成项目并自动加壳发布
LabVIEW生成.NETDLL——C#下调用NI数据采集设备功能一种方法 [原创www.cnblogs.com/helesheng]
C# txt文本文件读取写入,
C# Newtonsoft.Json.JsonConvert.SerializeObject生成格式化JSON字符串
API接口安全设计方案
C#性能优化总结
利用代码生成工具Database2Sharp生成ABP VNext框架项目代码
C# 读取txt文件生成Word文档
windows平台分布式微服务解决方案(5)--Web服务/WebApi负载均衡
C#获得类型Type实现接口列表,支持排除基类实现接口
GZUpdate自动升级服务 .NET C/S Winform客户端程序自动升级演示
windows平台分布式微服务解决方案(1)--UUID全球通用唯一识别码
C#中反射:获取类直接实现接口并排除继承上级接口

联系我们
联系电话:15090125178(微信同号)
电子邮箱:garson_zhang@163.com
站长微信二维码
微信二维码