C#中的ReferenceEquals、Equals以及==

C#中有一共有四种相等性判断方法:

//Object中定义的三个方法
public static bool ReferenceEquals(object objLeft, object objRight);
public static bool Equals(object objLeft, object objRight);
public virtual bool Equals(object obj);//双等号
public static bool operator == (MyClass left, MyClass right)

①Object.ReferenceEquals(left, right)静态方法:从名称中便可知它用来比较两者是否是相同的引用,我们也永远不应该去重写该方法。它对于值类型对象的比较永远返回false;对于两个null的比较永远返回true。

②Object.Equals(left, right)静态方法:该方法也永远不需要重写,因为它最终会把判断权交给参数left的实例Equls方法(代码如下),因此没有必要重写该方法,只需要保证实例Equals返回想要的结果即可:

public static bool Equals(object left, object right)
{if(object.ReferenceEquals(left,right)) //如果引用相同,则必定相等(包含两个都是null的情况){return true;}if(object.ReferenceEquals(left ,null)|| object.ReferenceEquals(null,right)) //若只有一个是null,则必定不等{return false;}return left.Equals(right);//两个都不是null,且也不是同一个引用,则根据left的实例Equals方法来判断。
}

③Object中的实例方法Equals,因为它是虚方法,所以可以在其他类中重写它。该方法的默认实现还是比较两者是否为同一个引用,即相当于ReferenceEquals。但是微软在所有值类型的基类System.ValueType中重写了该方法,用来比较值相等。

  • 在值类型中,我们仍然可能要重写该方法,以提高性能(默认方法的性能不高),另外如果我们的struct中包含了引用类型的成员,则应该重写该方法。
  • 在引用类型中,如果类的实例要作为字典的键,则应该重写Equals方法,使之比较值,而不是引用。

重写Equals应该遵循的原则:自反性、对称性、传递性。即:a=a;若a=b,则b=a;若a=b,b=c,则a=c;另外两个对象要么相等要不不等,所以该方法不应该抛出异常。下面是重写模板:

public class MyClass:IEquatable<MyClass>
{//重写Object中的Equals方法public override bool Equals(object obj){if (object.ReferenceEquals(obj, null)) //首先判断obj不能为空,否则后面对obj调用任何方法都将报错{return false;}if(object.ReferenceEquals(this,obj)) //在C#中this永远不会为空{return true;}if(this.GetType() != obj.GetType()){return false;}return this.Equals(obj as MyClass);}//实现IEquatable<T>中的Equals方法public bool Equals(MyClass other){//省略return true;}
}

④比较运算符==:对于引用类型,默认是比较引用的(System.String除外),对于值类型默认比较值,对于自定义的结构,如果不显示重载operator ==方法,则无法使用==。

  • 由于在C#中要求比较运算符必须成对重载,重载==运算符的同时也必须重载!=运算符,否则也会产生编译错误。
  • 如果要重载的话,运算符"=="、"!="  与  Equals方法、GetHashCode方法应该同时被重载,因为他们应该保持同样的相等逻辑。但不要再==中调用Equals,最好是在Equals中调用==。

C#四种相等性判断方法 equals,referenceEquals相关推荐

  1. WindowsServer2012史记7-茴香豆的五种写法和四种”显示计算机”的方法

    消失的"计算机"? [这周九叔工作比较忙,还有其他琐事缠身,因此SystemCenter2012SP1系列的发布稍慢,抱歉了各位.] 众所周知,WindowsServer2012和 ...

  2. python单例模式继承_Python四种实现单例模式的方法

    在这之前,先了解super()和__new__()方法 super()方法: 返回一个父类或兄弟类类型的代理对象,让你能够调用一些从继承过来的方法. 它有两个典型作用: a. 在单继承的类层次结构中, ...

  3. java中高效遍历list_Java中四种遍历List的方法总结(推荐)

    实例如下: package com.ietree.basic.collection.loop; import java.util.ArrayList; import java.util.Iterato ...

  4. A*寻路中第四种烘培寻路方法Recast Mesh方法:

    A*寻路中第四种烘培寻路方法Recast Mesh方法: 全地形烘培

  5. 随机变量列的四种收敛性

    极限定理是研究随机变量列的收敛性,在学习中遇到了随机变量列的四种收敛性:几乎处处收敛(a.e.收敛).以概率收敛(P-收敛).依分布收敛(d-收敛).k阶矩收敛,下面是对它们的吐血整理. 考虑一个随机 ...

  6. 计算机屏幕出现条纹w7,win7电脑屏幕出现条纹四种原因和解决方法

    在运行Win7旗舰版系统的时候屏幕突然出现条纹,虽然还可以正常操作,但是眼睛看久了会很累,很多人就会担心是不是屏幕坏了.遇到win7电脑屏幕出现条纹问题怎么办呢?首先我们要知道故障原因,然后在对症下药 ...

  7. 服务器显示器蓝屏怎么办,win7系统经常发生显示器蓝屏四种原因和解决方法

    在win7旗舰版系统中,显示器发生蓝屏属于常见问题之一,相信很多用户都有遇到过,最烦恼就是工作到一半数据没有保存就发生蓝屏了.其实造成显示器发生蓝屏的原因有很多种,小编给大家收集总结win7系统经常发 ...

  8. java遍历list_Java中四种遍历List的方法总结(推荐)

    实例如下: package com.ietree.basic.collection.loop; import java.util.ArrayList; import java.util.Iterato ...

  9. linux无线网卡连接不稳定怎么办,无线网络信号不稳定的四种原因及解决方法

    宽带路由器在一个紧凑的箱子中集成了路由器.防火墙.带宽控制和管理等功能,具备快速转发能力,灵活的网络管理和丰富的网络状态等特点.在使用无线网络过程中,无线网络信号不稳定,忽强忽弱是大家经常遇到的问题, ...

最新文章

  1. 工作如果没有方法,光靠苦力是不行的
  2. 青少年电子信息智能创新大赛 -- 图形化编程挑战赛初赛试题说明
  3. P1892 [BOI2003]团伙(并查集,反集)难度⭐⭐★
  4. ST17H26读ID卡调试过程
  5. jasig CAS实现单点登录(数据库认证)
  6. 设计模式- 策略模式
  7. 等待ajax,等待Ajax调用(post)完成
  8. windows系统如何cmake_Windows操作系统如何快速增加分区?建议收藏
  9. 35修改tomcat端口
  10. graphviz python_python中使用scikit-learn和pandas决策树进行iris鸢尾花数据分类建模交叉验证...
  11. Visual Studio 2010 Ultimate敏捷之道:特性解析
  12. 虚拟机VMware14安装教程以及搭建openEuler-20.03-LTS-x86_64-dvd.iso系统教程(网盘中也包含了Ubuntu 16.04的.ios文件)
  13. 新品上市|A股场内衍生品大盘点
  14. 股市基础知识、主力建仓、派发出货【四】
  15. limits学习之各数据类型的范围及相关属性
  16. Word 里文字对齐推荐这4种方法
  17. OPPOR9Android 6.0过程,超简单 OPPOR9升级Android 6.0系统 详细教程
  18. 关于iOS的通讯录开发权限的说明笔记
  19. python plot如何保存图片_Matplotlib 保存图片、图画接口和显示中文的使用方法
  20. 深入理解Java异常机制

热门文章

  1. java ftp 中文上传_java实现ftp文件上传下载,解决慢,中文乱码,多个文件下载等问题...
  2. mysql恢复语句报错_php对于mysql恢复数据的时候,只能恢复一条!然后就会报错!但把sql语句直接贴到数据库里面是可以执行的!...
  3. java 枚举使用例子_Java枚举详解及使用实例(涵盖了所有典型用法)
  4. linux下本地的源的格式,[Linux]CentOS7搭建/配置:YUM仓库/源[本地源/HTTP源/自建源仓库...
  5. 图像处理——傅里叶变换
  6. ipython怎么安装numpy_在TensorFlow教程中安装numpy后仍然无法导入
  7. burp爆破线程设置多少_多线程到底需要设置多少个线程?
  8. solidworks无法获得下列许可standard_SolidWorks2020安装无法获得下列许可SOLIDWORKS Standard怎么解决?...
  9. python字典和集合双向索引_Python-为什么字典和集合中的顺序是任意的?
  10. linux开源软件经验,Ubuntu Linux经验汇总