c# 复写Equals方法的实现
作者:桃花换小鱼干儿 发布时间:2023-06-09 01:35:35
应用情景:
很多标准的方法都是利用Object.Equals方法来做对比的,例如LIst.Remove
假设 某些情景下我们希望引用类型判断“相等”时不去看地址是不是同一个,而是看某些属性是不是一样就可以了。(例如身份证ID是一个就认为是同一个人)
复写方法如下范例所示:
Main{
List<People> nList = new List<People> { new People( 1 ), new People( 2 ), new People( 3 ) };
People onePeople = new People( 1 );
nList.Remove( onePeople );
}
class People
{
public People( int nID )
{
ID = nID;
}
int ID;
public override bool Equals( object obj )
{
return Equals( obj as People );
}
bool Equals( People other )
{
return other != null
&& ID == other.ID;
}
}
P.s. 最好也重新overide GetHashCode方法:
(7跟13只是常用的手法,拿質數來乘,確保hash code是獨一無二),也可以加入 ^ 计算
public override int GetHashCode()
{
int hash =13;
hash = (hash * 7) + ID== null ? 0 : ID.GetHashCode();
}
原因是:
1.Equal是判断是否指向同一个地址
2.每个对象都会有一个独一无二的HashCode
一旦override了Equal方法,却不override GetHashCode方法会导致两个判断为相同(利用Equal判断)的对象,Hash值却不同。
承上,在使用到HashCode的地方(例如Dictionary中的key),两个相同对象可能会被重复加入到Dictionary中
什么时候需要重写 Equals() 方法
引用类型:
只有当需要修改该引用类型所定义的语义时,才应该重写实例版本的 Equals() 方法。如果类型需要采用值语义而不是引用语义(或者说,需要按照对象内容而不是对象身份来进行比较),那么就应该针对这个类型重写实例版本的 Object.Equals() 方法。
引用类型一般不需要重写 operator==()。
值类型:
创建值类型的时候,总是应该针对这个类型重写 ValueType.Equals() 方法。
因为值类型都继承自 System.ValueType 类,System.ValueType 类默认通过反射来实现比较,效率不够高。
值类型中默认的 == 运算符会默认通过反射进行比较,因此,也应该重写 == 操作符。
重写 Equals() 方法时的注意事项
Equals() 方法必须满足等同关系的 3 项数学性质:自反性、对称性、可传递性。
Equals() 方法决不应该抛出异常。
重写 Equals() 方法时,只有在基类型的 Equals(object) 不是由 System.Object 或 System.ValueType 所提供的情况下,才需要调用基类型的版本。
重写 Equals() 的时候,还应该让该类型实现 IEquatable<T> 接口。
重写 Equals() 方法后,通常应该同时重写 GetHashCode() 方法。
重写 GetHashCode() 方法时的注意事项
如果 Equals() 方法认定两个对象相等,那么这两个对象的 HashCode 也必须相同;
对任意对象来说,其 HashCode 必须在生命周期内保持不变;
HashCode 计算方法应该将其值均匀地映射到各个整数上,避免堆集。
一种常用的 HashCode 算法是:对类型中的每个相互独立的不可变字段调用 GetHashCode() 方法,并对返回的 HashCode 进行异或(XOR)运算,将得到的最终结果作为对象本身的 HashCode 。
来源:https://blog.csdn.net/qq_41617697/article/details/123716144


猜你喜欢
- Solr我还是个菜鸟,写这一些文章只是记录一下最近一段时间学习Solr的心得。 Solr是什么? 最近我学Solr的时候,一直看到一句话,S
- 先为啥要纯手工打造呢,因为对方是用C++做的,我按照他们给出的WSDL实现了一个WebService,结果他们完全不能调用。具体是他们调用的
- 前言Kotlin越来越流行,在Google的推动下发展的很迅猛,现在的项目大多使用上了Kotlin,其简练的语法糖确实能减少不少代码。Ada
- 一、Unity Shader基础1、创建和使用Shader在Unity中Shader一般由两种用途:指定给材质,用于物理渲染;指定给脚本,用
- IDEA单元测试报错:Class not found:xxxx springboot报错引入了新依赖,想着在测试模块进行测试。结果报错说Cl
- 目录前言RenderObject 类继承层级解析RenderBox叶节点与父节点控件的测量与布局performResize 和 perfor
- 这几年一直在做手机上和电视盒的App,几乎没有考虑过横竖屏切换的问题。电视盒好说,横屏不变,你要是给它设计个竖屏人家也没机会使;而手机上的应
- 在我们做项目的过程中,有可能会遇到跨域请求,所以需要我们自己组装支持跨域请求的JSONP数据,而在4.1版本以后的SpringMVC中,为我
- 本文实例介绍的是Android的Tab控件,Tab控件可以达到分页的效果,让一个屏幕的内容尽量丰富,当然也会增加开发的复杂程度,在有必要的时
- Android开发,触控无处不在。对于一些 不咋看源码的同学来说,多少对这块都会有一些疑惑。View事件的分发机制,不仅在做业务需求中会碰到
- 一、前言 网上有许多的多线程断点续传操作,但总是写的很云里雾里,或者
- //字符串的内存驻留机制 public static v
- 在 Intellij Idea 中,我们需要设置 Settings 中的 Java Compiler 和 Project Structure
- 提出问题下面所给代码编译时正常,但是执行时会出错,请指出程序在执行时能够执行到编号为(1)(2)(3)的代码行中的哪一行。using Sys
- 一、Thymeleaf简介Thymeleaf是面向Web和独立环境的现代服务器Java模板引擎,能够处理HTML,XML,JavaScrip
- 本文实例为大家分享了java实现购物车功能的具体代码,供大家参考,具体内容如下1 需要实现1、实现淘淘商城的购物车功能2 购物车功能2.1
- 本文实例讲述了C#中File类的文件操作方法。分享给大家供大家参考。具体分析如下:File类,是一个静态类,主要是来提供一些函数库用的。静态
- Java为什么不浪(long)学而时习之不亦说乎,继续温习Java。今天使用switch时,不小心写了如下代码,报错如下。 public s
- java调用外部程序的方法 在一个java应用中,可能会遇到这样的需求,就是需要调用一些外部的应用做一些处理,比如调用excel,
- 篇首,完全没有技术含量的帖子,高手略过,只为十几年后重新捡起的我爱好玩玩。。。起因,一个朋友说他下载了很多短视频,但只需要要其中的一小截,去