1.前言

== Equals ReferenceEquals 三个相等性测试,是.NET提供给程序员使用的三个方法,他们之间有什么联系和区别,你真的仔细研究过?虽然之前也多多少少知道一点,但是有时候又难免混淆他们之间的概念和所适用的场合,决定做一个总结系统的描述这三个宝宝

2.值类型比较和引用类型比较

在编程中实际上我们只需要这两种比较,c#中类型也就这两种

  (1)值类型的比较:一般我们就是判断两个值类型实例的各自包含的值是否相等

  (2)引用类型的比较:由于引用类型在内存中的分布有两部分,一个是引用类型的引用(存在于线程栈中),一个是引用类型的值(存在于托管堆);所以我们比较引用类型也就存在两种比较

默认情况下:值类型比较的是两个值是否相等(不装箱情况下),引用类型比较的是两个引用是否相等。

3.==, Equals,ReferenceEquals 的阐述
3.1==

定义:静态相等符号,对应存在的!=,这个符号是一个可以重载的二元操作符,可以用于比较两个对象是否相等。使用==比较对象时,C#在编译时就决定了所比较的类型,而且不会执行任何虚方法(Object.Equals)。这是大家所期望的相等行比较。

  • 对于内置值类型,==判断的是两个对象的代数值是否相等。它会根据需要自动进行必要的类型转换,并根据两个对象的值是否相等返回true或者false
  • 对于引用类型,则==一般情况下比较的这是引用类型的引用是否相等。

注意:但是某些内置的引用类型重载了==符号,例如string就重载==,使其比较的不是两个字符串的引用,而是比较的两个字符串字面量是否相等,如下图,所以对于引用类型最好不要使用==符号进行相等性比较,避免混淆。【对于引用类型利用==除了string是比较其值外,其余都是比较其引用,因为string是经常需要操作,所以会直接比较其值,所以会对其特殊对待,所以如果遇见特殊的引用类型需要查看一下是否进行了==重载,默认情况大家都可以把==在比较引用类型时当成比较引用!

  值类型的==比较:虽然i和j在栈上具有不同的内存空间,但是他们的代数值都为5;m和n类型被自动转换并比较代数值

 int i = 5;int j = 5;Console.WriteLine(i == j);//值类型比较代数值 输出Trueint m = 6;double n = 6.0;Console.WriteLine(m == n);//类型自动转换并比较数值 输出True

  引用类型==比较:如下代码,两个object对象都在堆上申请了空间,在线程栈上存在两个不同的引用,所以输出结果为False

object obj1 = new object();
object obj2 = new object();
Console.WriteLine(obj2==obj1);//引用类型比较引用 输出False

 3.2 Equals

  定义:Equals属于Object的实例方法,用于比较两个对象的引用是否相等,注意:对于Object对象比较的是引用!

     然而对于值类型,类型相同(不会进行类型自动转换),并且数值相同(对于struct的每个成员都必须相同),则Equals返回 true,否则返回false。这是为什么呢?                 这是因为内置的值类型都重写了Object.Equals方法,所以值类型的Equals方法与引用类型的Equals就产生了不同的效果。

Equals在程序运行时决定比较的类型--根据对象的实际类型进行比较,根据对象的类型调用他们各自的Equals虚方法。

            int i = 5;int j = 5;Console.WriteLine(i.Equals(j));//值类型比较 输出Trueint m = 6;double n = 6.0;Console.WriteLine(m.Equals(n));//类型不会自动转换并比较数值 输出Falseobject obj1 = new object();object obj2 = new object();Console.WriteLine(obj2.Equals(obj1));//引用类型比较 输出FalseConsole.WriteLine(obj2.Equals(string.Empty));//输出False,比较量对象的类型不同直接返回False      

3.3 ReferenceEquals

  定义:Object的静态方法,比较两对象的引用是否相等,值类型和引用类型都是一样。

            int i = 5;int j = 5;Console.WriteLine(object.ReferenceEquals(i, j));//输出Falseint m = 6;double n = 6.0;Console.WriteLine(object.ReferenceEquals(m, n));//输出Falseobject obj1 = new object();object obj2 = new object();Console.WriteLine(object.ReferenceEquals(obj1, obj2));//输出False
4.三种比较方法的相同和区别

通过以上的探讨我们知道

ReferenceEquals比较对象的引用是否相同,而且是安全的比较
==和Equals异同

相同点: 对于值类型 都是比较代数值是否相等
不同点:(1)对于值类型比较,==会进行类型的自动转换,然后比较代数值,Equals则不会进行转换,先比较类型,再比较值,如果类型不同直接返回false
   (2)==比较是安全的比较,也就是说两对象为任何值都可以进行比较,不会抛出异常;而Equals的比较则是不安全的,由于在Equals在运行时才会进行真正的比较,有可能调用Equals的调用者是NULL,编译通过,但是运行时则会抛出异常

所以对于引用类型是要使用实例的Equals进行比较时,一定不要忘记检查调用者对象是否为空。而Object提供的静态Equals方法也是安全的不需要检查,下面的方法等效于Object提供的静态Equals方法

public static bool AreEqual(object obj1, object obj2){if (obj1 == null)return obj2 == null;return obj1.Equals(obj2);}
由于本人才学识浅,描述难免纰漏,如有错误,欢迎指出。么么!
参考资料:http://www.cnblogs.com/yang_sy/p/3582946.htmlhttp://www.cnblogs.com/zagelover/articles/2741409.html

转载于:https://www.cnblogs.com/bad-man/p/7965431.html

【转载】C#扫盲之:==/Equals /ReferenceEquals 异同的总结,相等性你真的知道吗?相关推荐

  1. Equals,ReferenceEquals,==的区别

    Equals,ReferenceEquals,==的区别 在.net中有几种比较相等的方法 object的静态ReferenceEquals() object的静态Equals() object的示例 ...

  2. == Equals ReferenceEquals 的区别

    .net 中有几种比较相等的方法 object 的静态ReferenceEquals() object 的静态Equals() object 的实例Equals() 运算符== Object 中的cl ...

  3. 【转载】扫盲概念RPA

    PRA是啥玩意? 一.RPA是什么? RPA : Robotic Process Automation(机器人流程自动化).它是一种软件或者平台,根据预先设定的程序,通过模拟并且增强人类与计算机的交互 ...

  4. 关于 equals 和 hashCode,看这一篇真的够了!

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接: https://blog.csdn.net/CringKong/article/de ...

  5. 【软件构造】equals()、hashCode()及引用等价性、对象等价性、观察等价性、行为等价性

    文章目录 一.等价关系 二.引用等价性和对象等价性 1.引用等价性 ==: 2.对象等价性equals: 三.hashCode()方法 1.对于不可变类型 2.对于可变类型 四.观察等价性和行为等价性 ...

  6. [转载]迷雾中的华为“自杀门”:当狼性成为一种文化

    原文:http://tech.sina.com.cn/t/2008-04-02/14372116251.shtml 迷雾中的华为"自杀门" 当狼性成为一种文化 刚刚走出" ...

  7. C#中的==、Equal、ReferenceEqual(转载)

    1. ReferenceEquals, == , Equals  Equals , == , ReferenceEquals都可以用于判断两个对象的个体是不是相等. a) ReferenceEqual ...

  8. java比较两个对象重写,不重写equals进行两个对象间的深度比较

    背景 我们知道在Java中比较两个对象是否相同,可以有多种方法,最常见的就是 == 和 equals 方法.但是由于==对比的是对象引用本身,因此重写equals才是最常用和可靠的比较两个对象是否相同 ...

  9. 扫盲,为什么分布式一定要有Redis?

    转载自   扫盲,为什么分布式一定要有Redis? 考虑到绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,只会 Set Value 和 Get Value 两个操作,对 Redis 整体 ...

最新文章

  1. 转 Hystrix入门指南 Introduction
  2. python一箭穿心代码怎样复制,Python Decimal copy_sign()用法及代码示例
  3. http://offlineinstallersofts.com/
  4. windows + vscode 远程配置
  5. bash 的进站欢迎提示
  6. C语言高级编程:汇编分析i++和++i
  7. 3 个月如何从小白到 Python 高手?清华博士带你入门带你飞!
  8. 计算机是通过 来访问存储单元的,计算机是通过____来访问存储单元的
  9. MySQL JDBC URL中几个重要参数说明
  10. 计算机软驱的连接方式,岛精仿真软驱、斯托尔USB软驱、斯坦格电脑横机软盘改U盘...
  11. 如何将U盘刻录为系统启动盘?
  12. 为什么有一些PDF转换成Word后是乱码?
  13. vmware安装win10并使用xshell成功连接及虚拟机中win10设置静态ip
  14. QQ音乐爬虫程序详细解析(一)——歌曲下载模块
  15. 计算机b类b级2020,CPU天梯图2020_笔记本CPU天梯图2020最新版【7月更新】-太平洋IT百科...
  16. 迅为iTOP-4418开发板最新资料及例程
  17. win10无限蓝屏_Win10升级系统后蓝屏或无限重启解决办法
  18. 概率论--贝叶斯法则
  19. 分布式计算原理之分布式协调与同步(1)——分布式互斥
  20. P4720 【模板】扩展卢卡斯

热门文章

  1. iOS - OC NSUserDefaults 数据存储
  2. oracle数据库----SQL语句的实践(应用实例)
  3. 使用struts2+JQuery实现的简单的ajax例子
  4. C/C++:sizeof('a')的值为什么不一样?
  5. docker容器时区与宿主机不一致的解决方法
  6. 【MongoDB】MongoDB备份方法
  7. 获取预制和获取gameObject
  8. android开发(30) 使用WebView,点击网页中的链接建立QQ 临时会话 WPA
  9. List集合add使用过程中出现的错误
  10. php 面向对象学习