C#中的ReferenceEquals、Equals以及==
https://www.cnblogs.com/ArtofDesign/p/3615212.html
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#中的ReferenceEquals、Equals以及==的更多相关文章
- java中hashcode()和equals()的详解
今天下午研究了半天hashcode()和equals()方法,终于有了一点点的明白,写下来与大家分享(zhaoxudong 2008.10.23晚21.36). 1. 首先equals()和hashc ...
- 2)Java中的==和equals
Java中的==和equals 1.如果比较对象是值变量:只用== 2.如果比较对象是引用型变量: ==:比较两个引用是不是指向同一个对象实例. equals: ...
- C# 中的 == 和 equals()有什么区别?
如以下代码: 1 2 3 4 5 6 7 8 9 int age = 25; short newAge = 25; Console.WriteLine(age == newAge); //t ...
- java中的==和equals的区别
关于JAVA中的==和equals函数的区别 今天在研读Thinking in java 时注意到==和equals的区别,于是就通过查看JDK_API才读懂了他们的区别,于是将心得分享一下,望批评指 ...
- java中的==、equals()、hashCode()源码分析
转载自:http://www.cnblogs.com/xudong-bupt/p/3960177.html 在Java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际 ...
- java中的==、equals()、hashCode()源码分析(转载)
在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. == java中的==是比较两个对象在JVM中的地址.比较好理解.看下面的代码: ...
- 深入分析Java中的 == 和equals
关于Java中的 == 和equals的解释请看这位博主的文章 :http://www.cnblogs.com/dolphin0520/p/3592500.html 以下是我对这篇文章的一些扩展. 对 ...
- java中的==、equals()、hashCode()
java中的==.equals().hashCode()源码分析 在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. == java中 ...
- Java中的==和equals( )方法
在Java中,equals和==都是用于检测两个字符串是否相等,返回类型也都是boolean值,但是二者内部处理却不一样. ==与equals( ) ==在Java中是一个二元操作符,用于比较原生类型 ...
- 听说你还搞不定java中的==和equals?
相信很多读者关于==和equals懂了又懵,懵了又懂,如此循环,事实上可能是因为看到的博客文章之类的太多了,长篇大论,加上一段时间的洗礼之后就迷路了.本篇文章再一次理清楚.当然如果觉得本文太啰嗦的话, ...
随机推荐
- error Unnecessary return statement no-useless-return
语法错误 原本是 addUser() { this.$refs.addFormRef.validate((valid) => { if (!valid) return ...
- 报错信息;Cannot execute request on any known server 解决;sprigcloud;跑本地但是服务一直在eureka
配置文件加上: eureka.client.register-with-eureka=falseeureka.client.fetch-registry=false
- unity 实现Game窗口的Stats 【转自蛮牛】
using UnityEngine;using System.Text;using UnityEditor; public class ShowFps : MonoBehaviour{ public ...
- redis底层数据结构之双向链表(linkedlist)
双向链表(linkedlist) redis的双向链表(linkedlist)是基于链表的一种数据结构 链表是一种常见的基础数据结构,是一种非顺序存储数据的线性表,在每一个节点里存储了下一个节点的指针 ...
- cross-env 运行跨平台设置和使用环境变量的脚本
1.1 cross-env是什么 运行跨平台设置和使用环境变量的脚本 1.2 出现原因 当您使用 NODE_ENV=production, 来设置环境变量时,大多数 Windows 命令提示将会阻塞( ...
- jumpserver运行源码
本文运行流程介绍来自jumpserver版本号:v2.23.2 入口文件 run_server.py run_server中通过subprocess.call,用python3运行了同级目录下jms, ...
- Selenium私房菜系列9 -- Selenium RC服务器命令行参数列表【VV】
使用示例: java -jar selenium-server.jar [-interactive] [options] -port <nnnn>: selenium服务器使用的端口号(默 ...
- js原生判断数字类型
js判断数字类型汇总最近在写代码的时候,有些逻辑需要判断数字类型,等用到的时候才发现自己了解的方法不太严密,然后就决心查资料汇总了解下有哪些方法比较严密 第一种:typeof + isNaN使用typ ...
- slitaz5安装vim,sakura终端命令行打不开
刚开始安装了vim后,vim提示libtinof.so.6打不开.在网上查,发现可能是库缺少.然后查看了依赖库文件 ldd /usr/bin/vim 发现果然缺少了 libncurses.so.6 的 ...
- Go组件库总结之介入式链表
本篇文章我们用Go封装一个介入式的双向链表,目的是将链表的实现和具体元素解耦.文章参考自:https://github.com/brewlin/net-protocol 1.元素的接口 type El ...