细说C#的ReferenceEquals,Equals和==比较运算符
C# 中有两种不同的相等:引用相等和值相等。值相等是大家普遍理解的意义上的相等:它意味着两个对象包含相同的值。例如,两个值为 2 的整数具有值相等性。引用相等意味着要比较的不是两个对象,而是两个对象引用,这两个对象引用引用的是同一个对象。这可以通过简单的赋值来实现,如下面
System.Object a = new System.Object();
System.Object b = a;
System.Object.ReferenceEquals(a, b); //returns true
在上面的代码中,只存在一个对象,但存在对该对象的多个引用:a 和 b。由于它们引用的是同一个对象,因此具有引用相等性。如果两个对象具有引用相等性,则它们也具有值相等性,但是值相等性不能保证引用相等性。
若要检查引用相等性,应使用 ReferenceEquals
1、比较引用类型相等性
System.Object定义了3个不同方法,来比较对象的相等性:ReferenceEquals()和两个版本的Equals()。再加上比较运算符(==)
ReferenceEquals(),静态方法,不能被重写,测试两个引用是否引用类的同一个实例,特别是两个引用是否包含相同的地址。
如果提供的两个引用引用同一个对象实例,则ReferenceEquals()总是返回true,否则返回false,但是他认为null等于null:
System.Object a = new System.Object();
System.Object b = a;
System.Object c=new System.Object();
System.Object.ReferenceEquals(a, b); //returns true
bool flag=ReferenceEquals(null,null) //return true
bool flag1=ReferenceEquals(a,c) //return false
bool flag2=ReferenceEquals(null,a) //return false
另外,ReferenceEquals()在应用于值类型是,他总是返回false,因为为了调用这个方法,值类型需要装箱到对象中,
即使使用下面的代码:
bool flag=ReferenceEquals(v,v); //v是值类型
也会返回false,应为在转换每个参数时,v都会被单独装箱,这意味着会得到不同的引用,也就是说ReferenceEquals() 来比较值类型
实际上没什么意义。
2、静态的Object.Equals(Object objA,Object objB)方法
如果如果objA 是与 objB 相同的实例,或者如果两者均为空引用,或者如果 objA.Equals(objB) 返回 true,则为 true;否则为 false。
Equals 的默认实现仅支持引用相等,但派生类可重写此方法以支持值相等。
对于引用类型,相等定义为对象相等;即这些引用是否引用同一对象。对于值类型,相等定义为按位相等。ValueType 类支持值类型。
在调用 objA.Equals(objB) 前,此方法首先检查两个参数是否均为空引用。
String s1="Hello";
String s2="World";
String s3="Hello"; Object.Equals(s1,s2) //return false
Object.Equals(s1,s3) //return true s2=null;
Object.Equals(s1,s2) //return false s1=null;
s2=null;
Object.Equals(s1,s2) //return true
3、虚拟的 Object.Equals(obj)方法
如果指定的 Object 等于当前的 Object,则为 true;否则为 false。
此方法可由派生类重写。例如,如果两个对象表示相同的值,则许多基数据类型返回 true;否则返回 false。 此方法仅比较基元和对象。若要比较更复杂的结构(如对象数组),必须重写该方法。 下面的语句对于 Equals 方法的所有实现均必须为真。
Equals 的实现必须不引发异常。 对于某些类型的对象,最好让 Equals 测试值相等性而非引用相等性。如果两个对象具有相同的“值”,那么即使它们不是同一实例,这样的 Equals 实现仍返回 true。类型实施者决定对象的“值”的构成,但这通常是存储在对象的实例变量中的部分或全部数据。例如,String 的值基于字符串的字符;对于两个按同样的顺序包含完全相同的字符的字符串实例,String 类的 Equals 方法返回 true
int i=;
int j=;
bool flag=i.Equals(j); //只类型比较,返回true
double k=9.0;
bool flag1=i.Equals(k);// 类型不会自动转换并比较数值,返回false Object objA=new Object();
Object objB=new Object(); bool flag2=objA.Equals(objB); //引用比较,返回false
bool flag3=objA.Equals(String.Empty); //比较对象的类型不同,直接返回false
另外,Microsoft已经在System.ValueType类中重载了实例方法Equals(),以便对值类型进行合适的相等性测试。
如果调用sA.Equals(sB),其中sA和sB是某个结构的实例,则根据sA和sB是否在其所有的字段包含相同的值,而返回true或false
4、==比较运算符
对于值类型 都是比较代数值是否相等。
最好将比较运算符看作严格的值比较和严格的引用比较之间的中间项,在大多数情况下,下面代码表示正在比较引用:
bool b=(x==y) //x和y都是引用类型
在某些情况下,最好重写比较运算符(==),以执行值的比较,例如:System.String类,Microsoft重写了==运算符,用来比较
字符串的内容,而不是比较他们的引用
5、==和Equals异同
相同点: 对于值类型 都是比较代数值是否相等
不同点:(1)对于值类型比较,==会进行类型的自动转换,然后比较代数值,Equals则不会进行转换,先比较类型,再比较值,如果类型不同直接返回false
细说C#的ReferenceEquals,Equals和==比较运算符的更多相关文章
- Java提高篇——equals()方法和“==”运算符
equals() 超类Object中有这个equals()方法,该方法主要用于比较两个对象是否相等.该方法的源码如下: public boolean equals(Object obj) { retu ...
- java中的equals方法与"=="运算符解说
在编程的时候,我们可能经常会用到equals方法,那么这个equals方法和运算符“==”有什么样的区别? public class equal { /** * @param args */ publ ...
- C#中==运算符
在这篇博客中,我们将介绍如下内容: ==运算符与基元类型 ==运算符与引用类型 ==运算符与String类型 ==运算符与值类型 ==运算符与泛型 ==运算符与基元类型 我们分别用两种方式比较两个整数 ...
- C#中 Reference Equals, == , Equals的区别
原文地址:http://blog.csdn.net/wuchen_net/archive/2010/03/23/5409327.aspx ReferenceEquals, == , Equals Eq ...
- C#高级编程9-第7章 运算符和类型强制转换
运算符和类型强制转换 1.运算符 运算符的简化操作 条件运算符: if-else的简化操作,也称三元运算符.如果条件为真,返回一个值,为假返回另外一个值. condition?true_value:f ...
- String类中的equals()方法
在Java中,每一个对象都有一个地址空间,在这空间保存着这个对象的值. equals 比较的是值,==比较的地址以及值. 01: public class StringExample02: {03: ...
- 快看Sample代码,速学Swift语言(3)-运算符
运算符是用来检查,更改或组合值的特殊符号或短语.Swift提供的很多常规的运算符,如+.-.*./.%.=.==等,以及逻辑运算的&&.||等等,基本上不需要重复介绍,我们在这里只需要 ...
- [知识库分享系列] 二、.NET(ASP.NET)
最近时间又有了新的想法,当我用新的眼光在整理一些很老的知识库时,发现很多东西都已经过时,或者是很基础很零碎的知识点.如果分享出去大家不看倒好,更担心的是会误人子弟,但为了保证此系列的完整,还是选择分享 ...
- 多个提高C#编程能力的建议
1.总是用属性 (Property) 来代替可访问的数据成员 2.在 readonly 和 const 之间,优先使用 readonly 3.在 as 和 强制类型转换之间,优先使用 as 操作符 4 ...
随机推荐
- 也谈HTTP协议
HTTP(HyperText Transfer Protocol,超文转移协议,超文本传输协议的译法并不严谨.) 一.网络基础 TCP/IP 1.1 TCP/IP 协议族 TCP/IP 协议族是互联网 ...
- B. Uniqueness
B. Uniqueness 给定一个序列,要求删除一段连续子段,满足删掉子段后每个元素唯一 求最小子段长度 枚举起点,二分子段长度 记得先sort 再unique #include<bits/s ...
- SQL的积累
SQL的积累学习(不常用的经常会忘记,所以以后用到的就会记在下面): --新增字段alter table t_Student add Test varchar(200)--删除字段alter tabl ...
- es索引基本操作(1)
1:创建索引 创建索引的时候可以通过number_of_shards和number_of_replicas来指定当前索引的分片和副本数量: PUT demo_index1 { " ...
- sqli-labs(35)
0X01 构造闭合 发现不需要闭合 ?id=- union ,database(), 0X02组合拳打法
- final修饰的类,其属性和方法默认是被final修饰的吗?
在论坛上,看到一个问题,当然,各位聪明的客官想必已经知道问题是什么了,嘿嘿,没错就是文章的标题:final修饰的类,其属性和方法默认是被final修饰的吗? 老实说,刚开始看到这个问题的时候,有点懵. ...
- SpringBoot 优雅的整合 Shiro
Apache Shiro是一个功能强大且易于使用的Java安全框架,可执行身份验证,授权,加密和会话管理.借助Shiro易于理解的API,您可以快速轻松地保护任何应用程序 - 从最小的移动应用程序到最 ...
- STL标准库-容器-set与map
STL标准库-容器-set与multiset C++的set https://www.cnblogs.com/LearningTheLoad/p/7456024.html STL标准库-容器-map和 ...
- HTTPS 证书制作及使用
一 证书的制作 进入jdk/bin,使用keytools.exe制作证书. 1.创建keystore 创建一个别名为serverkeystore的证书,该证书存放在名为server.keystore的 ...
- 异步编程:IAsyncResult异步编程模型 (APM)
http://www.cnblogs.com/heyuquan/archive/2013/03/22/2976420.html