【转载】C#扫盲之:==/Equals /ReferenceEquals 异同的总结,相等性你真的知道吗?
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 异同的总结,相等性你真的知道吗?相关推荐
- Equals,ReferenceEquals,==的区别
Equals,ReferenceEquals,==的区别 在.net中有几种比较相等的方法 object的静态ReferenceEquals() object的静态Equals() object的示例 ...
- == Equals ReferenceEquals 的区别
.net 中有几种比较相等的方法 object 的静态ReferenceEquals() object 的静态Equals() object 的实例Equals() 运算符== Object 中的cl ...
- 【转载】扫盲概念RPA
PRA是啥玩意? 一.RPA是什么? RPA : Robotic Process Automation(机器人流程自动化).它是一种软件或者平台,根据预先设定的程序,通过模拟并且增强人类与计算机的交互 ...
- 关于 equals 和 hashCode,看这一篇真的够了!
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接: https://blog.csdn.net/CringKong/article/de ...
- 【软件构造】equals()、hashCode()及引用等价性、对象等价性、观察等价性、行为等价性
文章目录 一.等价关系 二.引用等价性和对象等价性 1.引用等价性 ==: 2.对象等价性equals: 三.hashCode()方法 1.对于不可变类型 2.对于可变类型 四.观察等价性和行为等价性 ...
- [转载]迷雾中的华为“自杀门”:当狼性成为一种文化
原文:http://tech.sina.com.cn/t/2008-04-02/14372116251.shtml 迷雾中的华为"自杀门" 当狼性成为一种文化 刚刚走出" ...
- C#中的==、Equal、ReferenceEqual(转载)
1. ReferenceEquals, == , Equals Equals , == , ReferenceEquals都可以用于判断两个对象的个体是不是相等. a) ReferenceEqual ...
- java比较两个对象重写,不重写equals进行两个对象间的深度比较
背景 我们知道在Java中比较两个对象是否相同,可以有多种方法,最常见的就是 == 和 equals 方法.但是由于==对比的是对象引用本身,因此重写equals才是最常用和可靠的比较两个对象是否相同 ...
- 扫盲,为什么分布式一定要有Redis?
转载自 扫盲,为什么分布式一定要有Redis? 考虑到绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,只会 Set Value 和 Get Value 两个操作,对 Redis 整体 ...
最新文章
- 转 Hystrix入门指南 Introduction
- python一箭穿心代码怎样复制,Python Decimal copy_sign()用法及代码示例
- http://offlineinstallersofts.com/
- windows + vscode 远程配置
- bash 的进站欢迎提示
- C语言高级编程:汇编分析i++和++i
- 3 个月如何从小白到 Python 高手?清华博士带你入门带你飞!
- 计算机是通过 来访问存储单元的,计算机是通过____来访问存储单元的
- MySQL JDBC URL中几个重要参数说明
- 计算机软驱的连接方式,岛精仿真软驱、斯托尔USB软驱、斯坦格电脑横机软盘改U盘...
- 如何将U盘刻录为系统启动盘?
- 为什么有一些PDF转换成Word后是乱码?
- vmware安装win10并使用xshell成功连接及虚拟机中win10设置静态ip
- QQ音乐爬虫程序详细解析(一)——歌曲下载模块
- 计算机b类b级2020,CPU天梯图2020_笔记本CPU天梯图2020最新版【7月更新】-太平洋IT百科...
- 迅为iTOP-4418开发板最新资料及例程
- win10无限蓝屏_Win10升级系统后蓝屏或无限重启解决办法
- 概率论--贝叶斯法则
- 分布式计算原理之分布式协调与同步(1)——分布式互斥
- P4720 【模板】扩展卢卡斯
热门文章
- iOS - OC NSUserDefaults		数据存储
- oracle数据库----SQL语句的实践(应用实例)
- 使用struts2+JQuery实现的简单的ajax例子
- C/C++:sizeof('a')的值为什么不一样?
- docker容器时区与宿主机不一致的解决方法
- 【MongoDB】MongoDB备份方法
- 获取预制和获取gameObject
- android开发(30) 使用WebView,点击网页中的链接建立QQ 临时会话 WPA
- List集合add使用过程中出现的错误
- php 面向对象学习