0

0

C#怎么判断两个对象的值是否相等_C#如何重写比较逻辑【详解】

尼克

尼克

发布时间:2026-03-14 15:41:01

|

368人浏览过

|

来源于php中文网

原创

Equals()默认比较引用,自定义类型需重写Equals和GetHashCode;record类型自动实现值相等;重写时须处理null、类型检查,并确保GetHashCode与Equals逻辑一致。

c#怎么判断两个对象的值是否相等_c#如何重写比较逻辑【详解】

Equals() 方法默认只比较引用,不是值

直接调用 object.Equals(a, b)a.Equals(b) 时,如果类型没重写 Equals,它就走 ReferenceEquals —— 也就是看是不是同一个内存地址。哪怕两个 Person 对象所有字段都一样,只要不是同一个实例,就返回 false

常见错误现象:new Person("Alice", 30).Equals(new Person("Alice", 30)) 返回 false,让人误以为“值相等逻辑失效了”,其实是根本没进值比较。

  • 只有 stringint 等内置值类型和部分 FCL 类型(如 DateTime)才默认实现了值语义的 Equals
  • 自定义类/结构体必须手动重写 Equals(object)GetHashCode(),否则哈希容器(如 DictionaryHashSet)会出问题
  • 重写时别忘了处理 null 参数和类型检查,否则运行时报 NullReferenceExceptionInvalidCastException

重写 Equals 时必须同步重写 GetHashCode

GetHashCode() 不是可选项,它是契约的一部分:如果两个对象 Equals 返回 true,它们的 GetHashCode() 必须相同;反之不成立。忽略这点,放进 Dictionary<TKey, TValue> 或用作 HashSet<T> 元素时,对象可能“消失”或查不到。

典型表现:dict[new Person("Bob", 25)] = "test"; 后再用另一个相同字段的 Person 去取,结果是 null —— 因为哈希桶找错了位置。

  • 用字段计算哈希码时,只选参与 Equals 判断的字段,且这些字段本身不能是可变的(比如 public string Name { get; set; } 就危险)
  • 推荐用 HashCode.Combine(field1, field2)(.NET Core 2.1+),比手写异或更安全,能更好处理 null 和顺序敏感问题
  • 如果类是可变的,又想支持值相等,考虑标记为 readonly struct 或用 record(C# 9+)自动处理

record 类型让值相等“开箱即用”

如果你用的是 C# 9 或更高版本,且模型本质是“数据载体”,record 是最省心的选择。它自动生成基于所有属性的 EqualsGetHashCode==!=,甚至带非破坏性修改(with 表达式)。

闪念贝壳
闪念贝壳

闪念贝壳是一款AI 驱动的智能语音笔记,随时随地用语音记录你的每一个想法。

下载

对比:写一个 5 字段的 class,手动重写 Equals + GetHashCode 至少要 20 行,还容易漏判 null 或类型;而 record 一行搞定。

  • 注意 record 默认按所有声明的属性(包括 init 属性)做值比较,不需要额外标注
  • 如果只想按部分字段比较(比如只比 ID),得显式重写 Equals,此时 record 的自动行为会被覆盖,但你仍得自己管 GetHashCode
  • record struct 在 .NET 7+ 支持,适合高性能场景,但要注意它仍是值类型,this 在方法中不可变(除非加 ref

== 运算符和 IEquatable<T> 是进阶优化点

== 默认也是引用比较。想让它支持值语义,得重载运算符;但光重载 == 不够,还得同时重载 !=,且内部逻辑必须和 Equals 一致,否则行为割裂。

IEquatable<T> 是为避免装箱和类型转换开销:当泛型集合(如 List<T>.Contains())调用 Equals 时,如果 T 实现了 IEquatable<T>,就会走泛型版本,跳过 object 参数的装箱和 as 转换。

  • 实现 IEquatable<Person> 后,必须让 Equals(Person other)Equals(object obj) 行为完全一致,否则调用方无法预测结果
  • == 运算符重载里,建议直接调用 Equals(other),不要重复写字段比较逻辑,避免维护不一致
  • 对引用类型,IEquatable<T> 主要提升泛型集合性能;对值类型,它还能避免不必要的装箱,值得加

最容易被忽略的一点:重写 Equals 后,如果这个类型会被序列化(比如 JSON.NET 或 System.Text.Json),值相等逻辑和序列化字段是否一致?比如你只在 Equals 里比了 ID,但序列化时把整个对象都存了,下游系统按全部字段判断相等,就会出现“代码里相等,存储后不等”的隐性不一致。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

457

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

549

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

337

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

82

2025.09.10

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1051

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

254

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1110

2024.03.01

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1570

2023.10.24

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11.3万人学习

C 教程
C 教程

共75课时 | 5.4万人学习

C++教程
C++教程

共115课时 | 21.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号