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和==比较运算符的更多相关文章

  1. Java提高篇——equals()方法和“==”运算符

    equals() 超类Object中有这个equals()方法,该方法主要用于比较两个对象是否相等.该方法的源码如下: public boolean equals(Object obj) { retu ...

  2. java中的equals方法与"=="运算符解说

    在编程的时候,我们可能经常会用到equals方法,那么这个equals方法和运算符“==”有什么样的区别? public class equal { /** * @param args */ publ ...

  3. C#中==运算符

    在这篇博客中,我们将介绍如下内容: ==运算符与基元类型 ==运算符与引用类型 ==运算符与String类型 ==运算符与值类型 ==运算符与泛型 ==运算符与基元类型 我们分别用两种方式比较两个整数 ...

  4. C#中 Reference Equals, == , Equals的区别

    原文地址:http://blog.csdn.net/wuchen_net/archive/2010/03/23/5409327.aspx ReferenceEquals, == , Equals Eq ...

  5. C#高级编程9-第7章 运算符和类型强制转换

    运算符和类型强制转换 1.运算符 运算符的简化操作 条件运算符: if-else的简化操作,也称三元运算符.如果条件为真,返回一个值,为假返回另外一个值. condition?true_value:f ...

  6. String类中的equals()方法

    在Java中,每一个对象都有一个地址空间,在这空间保存着这个对象的值. equals 比较的是值,==比较的地址以及值. 01: public class StringExample02: {03: ...

  7. 快看Sample代码,速学Swift语言(3)-运算符

    运算符是用来检查,更改或组合值的特殊符号或短语.Swift提供的很多常规的运算符,如+.-.*./.%.=.==等,以及逻辑运算的&&.||等等,基本上不需要重复介绍,我们在这里只需要 ...

  8. [知识库分享系列] 二、.NET(ASP.NET)

    最近时间又有了新的想法,当我用新的眼光在整理一些很老的知识库时,发现很多东西都已经过时,或者是很基础很零碎的知识点.如果分享出去大家不看倒好,更担心的是会误人子弟,但为了保证此系列的完整,还是选择分享 ...

  9. 多个提高C#编程能力的建议

    1.总是用属性 (Property) 来代替可访问的数据成员 2.在 readonly 和 const 之间,优先使用 readonly 3.在 as 和 强制类型转换之间,优先使用 as 操作符 4 ...

随机推荐

  1. JAVA批量文件下载

    1,看看我们封装的方法 方法中有三个参数:视频url,文件夹路径,视频名称. 调用方法进行下载. 2,看看结果 打印结果 文件夹下的视频下载成功 详细的参数配置可以参考我写的这篇文章:http://b ...

  2. 阿里云ECS服务器socket无法连接的问题

    把自己的项目部署到阿里云ecs服务器之后,只有127.0.0.1才能连接到服务器端,检查了阿里云安全组规则,以及socket绑定的地址无误后,发现没有开启服务器防火墙的对应端口. firewall-c ...

  3. [ZOJ3649]Social Net 题解

    前言 这道题目珂以说是很毒瘤了. 题解 首先克鲁斯卡尔求最大生成树,输出边权和. 倍增维护四个值:   链上最大值/最小值   链向上/向下最大差值 当然祖先是肯定要维护的. 然后把一条链经LCA分成 ...

  4. python3.x使用cxfreeze将.p打包成.exe

    之前写了一个使用ffplay批量查看格式为h264的图片,每次抽帧后都要打开pycharm编译器来运行程序,然后才能正常查看图片,或者在其他没有安装python环境的电脑中运行,很不方便.为此,在网上 ...

  5. prometheus 监控项

    此处记录prometheus监控项,exporter为 node_exporter vim rules.yml groups: - name: node rules: - alert: server_ ...

  6. 采用.bat批处理命令快速设置Java环境变量

    背景: java课程培训,每次到机房需要重新安装JDK,每次都采用图形界面进行操作比较麻烦(慢),于是在网上查了一下CMD命令设置系统环境变量的方法,再次记录下来. 设置方法: 1.找到JDK安装路径 ...

  7. [LeetCode]-algorithms-Median of Two Sorted Arrays

    There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...

  8. idea中查看一个类的调用用和被调用用关系

  9. eigen 中四元数、欧拉角、旋转矩阵、旋转向量

    一.旋转向量 1.0 初始化旋转向量:旋转角为alpha,旋转轴为(x,y,z) Eigen::AngleAxisd rotation_vector(alpha,Vector3d(x,y,z)) 1. ...

  10. MySQL——索引

    MySQL索引的概念 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构,通俗来讲索引就好比书本的目录,加快数据库的查询速度. 举个简单的例子,见下图: 注意:此例 ...