原文地址:http://blog.csdn.net/wuchen_net/archive/2010/03/23/5409327.aspx

ReferenceEquals, == , Equals Equals , == , ReferenceEquals都可以用于判断两个对象的个体是不是相等。

ReferenceEquals

ReferenceEquals是Object的静态方法,用于比较两个引用类型的对象是否是对于同一个对象的引用。对于值类型它总是返回false。

==

==是一个可以重载的二元操作符,可以用于比较两个对象是否相等。

对于内置值类型,==判断的是两个对象的代数值是否相等。它会根据需要自动进行必要的类型转换,并根据两个对象的值是否相等返回true或者false。

例如:

Int a = 100; Double b =100;

If(a == b) Console.WriteLine(“equal supports compare between different types!”);

上面这段程序将会输出: equal supports compare between different types!

而对于用户定义的值类型,如果没有重载==操作符,==将是不能够使用的。

例如:

Struct Userstruct1; Userstruct1 a; Userstruct1 b;

If(a == b) Console.WriteLine(“can == reach this far?”)

上面的这段代码是不能够通过编译的。可以通过重载使==作用于用户定义的值类型。

对于引用类型,== 默认的行为与ReferenceEquals的行为相同,仅有两个对象指向同一个Reference的时候才返回true。但是.NET Framework中的类很多对==进行了重载,例如String类的==与Equals的行为相同,判断两个字符串的内容是否相等。所以在应用中,对于 系统定义的引用类型建议不要使用==操作符,以免程序出现与预期不同的运行结果。

Equals

Equals 作为Object内置方法,Equals支持对于任意两个CTSCommon Type System对象的比较。 Equals它有静态方法和可重载的一个版本,下面的程序片断解释了这两个方法的用法,

int a = 5; int b = 5;

If(Object.Equals(a ,b)) // you can also use if(a.Equals(b)) { Console.WriteLine(“a is equal to b”); }

事实上,这两个版本的结果完全相同,如果用户重载了Equals,调用的都是用户重载后的Equals。Equals的静态方法的好处是可以不必考虑用于比较的对象是否为null。

Equals方法对于值类型和引用类型的定义不同,对于值类型,类型相同,并且数值相同(对于struct的每个成员都必须相同),则Equals返回 true,否则返回false。而对于引用类型,默认的行为与ReferenceEquals的行为相同,仅有两个对象指向同一个Reference的时 候才返回true。可以根据需要对Equals进行重载,例如String类的Equals用于判断两个字符串的内容是否相等。

//StringBuilder 类 //表示可变字符字符串。无法继承此类。

StringBuilder a = new StringBuilder(); a.Append("the test a"); String s1 = a.ToString(); String s2 = "the test a";

if (s2 == s1) Console.WriteLine("== returns true");

if (Object.Equals(s2, s1)) { Console.WriteLine("equals returns true"); }

if (Object.ReferenceEquals(s2, s1)) { Console.WriteLine("ReferenceEquals returns true"); }

这个实例将输出: == returns true equals returns true

注:对于String类,直接声明s1 = “the test a”的话,输出结果将包含 "ReferenceEquals returns true", 因为默认的,String对于声明的相同的字符串在堆上只保留一个Copy,所以s1与s2将会指向相同的Reference 。

在讨论了运算符,并简要介绍了等于运算符后,就应考虑在处理类和结构的实例时相等意味着什么。理解对象相等比较的机制对编写逻辑表达式非常重要,另外,对实现运算符重载和数据类型转换也非常重要,本章的后面将讨论运算符重载。

对象相等比较的机制对于引用类型(类的实例)的比较和值类型(基本数据类型,结构或枚举的实例)的比较来说是不同的。下面分别介绍引用类型和值类型的相等比较。

引用类型的相等比较

System.Object的一个初看上去令人惊讶的方面是它定义了3个不同的方法,来比较对象的相等性:ReferenceEquals()和Equals()的两个版本。再加上比较运算符==,实际上有4种进行相等比较的方式。这些方法有一些微妙的区别,下面就介绍这些方法。

================================================================

下面的最明了

1. ReferenceEquals()方法

ReferenceEquals()是一个静态方法,测试两个引用是否指向类的同一个实例,即两个引用是否包含内存中的相同地址。作为静态方法,它不能重写,所以只能使用System.Object的实现代码。如果提供的两个引用指向同一个对象实例,ReferenceEquals()总是返回true,否则就返回false。但是它认为null等于null:

SomeClass x, y;

x = new SomeClass();

y = new SomeClass();

bool B1 = ReferenceEquals(null, null);                //return true

bool B2 = ReferenceEquals(null, x);                //return false

bool B3 = ReferenceEquals(x, y);                  //return false because x and y

//point to different objects

2. 虚拟的Equals()方法

Equals()虚拟版本的System.Object实现代码也比较引用。但因为这个方法是虚拟的,所以可以在自己的类中重写它,按值来比较对象。特别是如果希望类的实例用作字典中的键,就需要重写这个方法,以比较值。否则,根据重写Object.GetHashCode()的方式,包含对象的字典类要么不工作,要么工作的效率非常低。在重写Equals()方法时要注意,重写的代码不会抛出异常。这是因为如果抛出异常,字典类就会出问题,一些在内部调用这个方法的.NET基类也可能出问题。

3. 静态的Equals()方法

Equals()的静态版本与其虚拟实例版本的作用相同,其区别是静态版本带有两个参数,并对它们进行相等比较。这个方法可以处理两个对象中有一个是null的情况,因此,如果一个对象可能是null,这个方法就可以抛出异常,提供了额外的保护。静态重载版本首先要检查它传送的引用是否为null。如果它们都是null,就返回true(因为null与null相等)。如果只有一个引用是null,就返回false。如果两个引用都指向某个对象,它就调用Equals()的虚拟实例版本。这表示在重写Equals()的实例版本时,其效果相当于也重写了静态版本。[Page]

4. 比较运算符==

最好将比较运算符看作是严格值比较和严格引用比较之间的中间选项。在大多数情况下,下面的代码:

bool b = (x == y);          //x, y object references

表示比较引用。但是,如果把一些类看作值,其含义就会比较直观。在这些情况下,最好重写比较运算符,以执行值的比较。后面将讨论运算符的重载,但显然它的一个例子是System.String类,Microsoft重写了这个运算符,比较字符串的内容,而不是它们的引用。

值类型的相等比较

在进行值类型的相等比较时,采用与引用类型相同的规则:ReferenceEquals()用于比较引用,Equals()用于比较值,比较运算符可以看作是一个中间项。但最大的区别是值类型需要装箱,才能把它们转换为引用,才能对它们执行方法。另外,Microsoft已经在System.ValueType类中重载了实例方法Equals(),以便对值类型进行合适的相等测试。如果调用sA.Equals(sB),其中sA和sB是某个结构的实例,则根据sA和sB是否在其所有的字段中包含相同的值,而返回true或false。另一方面,在默认情况下,不能对自己的结构重载==运算符。在表达式中使用(sA==sB)会导致一个编译错误,除非在代码中为结构提供了==的重载版本。

另外,ReferenceEquals()在应用于值类型时,总是返回false,因为为了调用这个方法,值类型需要装箱到对象中。即使使用下面的代码:

bool b = ReferenceEquals(v, v);          //v is a variable of some value type

也会返回false,因为在转换每个参数时,v都会被单独装箱,这意味着会得到不同的引用。调用ReferenceEquals()来比较值类型实际上没有什么意义。

尽管System.ValueType提供的Equals()默认重载肯定足以应付绝大多数自定义的结构,但仍可以为自己的结构重写它,以提高性能。另外,如果值类型包含作为字段的引用类型,就需要重写Equals(),以便为这些字段提供合适的语义,因为Equals()的默认重写版本仅比较它们的地址。

====================================================================================================================

http://msdn.microsoft.com/zh-cn/library/bsc2ak47(VS.80).aspx

Object.Equals 方法 (Object) 确定指定的 Object 是否等于当前的 Object。

参数 obj 与当前的 Object 进行比较的 Object。

返回值 如果指定的 Object 等于当前的 Object,则为 true;否则为 false。

备注 Equals 的默认实现仅支持引用相等,但派生类可重写此方法以支持值相等。

对于引用类型,相等定义为对象相等;即这些引用是否引用同一对象。对于值类型,相等定义为按位相等。ValueType 类支持值类型。

给实现者的说明 此方法可由派生类重写。例如,如果两个对象表示相同的值,则许多基数据类型返回 true;否则返回 false。 此方法仅比较基元和对象。若要比较更复杂的结构(如对象数组),必须重写该方法。 下面的语句对于 Equals 方法的所有实现均必须为真。在列表中,x、y 和 z 表示不为 空引用(在 Visual Basic 中为 Nothing) 的对象引用。

除涉及浮点型的情况外,x.Equals(x) 都返回 true。请参见 IEC 60559:1989, Binary Floating-point Arithmetic for Microprocessor Systems。

x.Equals(y) 返回与 y.Equals(x) 相同的值。

如果 x 和 y 都为 NaN,则 x.Equals(y) 返回 true。

当且仅当 x.Equals(z) 返回 true 时,(x.Equals(y) && y.Equals(z)) 才返回 true。

只要不修改 x 和 y 引用的对象,对 x.Equals(y) 的相继调用将返回相同的值。

x.Equals(空引用(在 Visual Basic 中为 Nothing)) 返回 false。

有关属于 Equals 方法的其他必需行为,请参见 GetHashCode。 Equals 的实现必须不引发异常。 对于某些类型的对象,最好让 Equals 测试值相等性而非引用相等性。如果两个对象具有相同的“值”,那么即使它们不是同一实例,这样的 Equals 实现仍返回 true。类型实施者决定对象的“值”的构成,但这通常是存储在对象的实例变量中的部分或全部数据。例如,String 的值基于字符串的字符;对于两个按同样的顺序包含完全相同的字符的字符串实例,String 类的 Equals 方法返回 true。 实现 IComparable 的类型必须重写 Equals。 重写 Equals 的类型也必须重写 GetHashCode;否则,Hashtable 可能不正常工作。 如果编程语言支持运算符重载,并且您选择了重载给定类型的相等运算符,则该类型必须重写 Equals 方法。这样的 Equals 方法实现必须返回与相等运算符相同的结果。遵照此准则有助于确保使用 Equals 的类库代码(如 ArrayList 和 Hashtable)的行为方式与应用程序代码使用的相等运算符的方式一致。 下面是针对实现值类型的准则: 考虑重写 Equals,以便在 ValueType 上获得比 Equals 的默认实现所提供的性能增强的性能。

如果重写 Equals 并且语言支持运算符重载,则必须重载值类型的相等运算符。

下面是针对实现引用类型的准则: 如果引用类型的语义是基于该类型表示某个(些)值的事实,则考虑对该类型重写 Equals。

即使大多数引用类型重写 Equals,它们也必须不能重载相等运算符。但是,如果实现的引用类型想要具有值语义(如复杂的数字类型),则必须重写相等运算符。

using System;

public class Sample {     void Method() {     Object Obj1 = new Object();     Object Obj2 = new Object();     Console.WriteLine(Obj1.Equals(Obj2)); //===> false     Obj2 = Obj1;     Console.WriteLine(Obj1.Equals(Obj2)); //===> true     } }

===================================================

http://msdn.microsoft.com/zh-cn/library/system.object.equals(v=vs.80).aspx

C#中 Reference Equals, == , Equals的区别的更多相关文章

  1. (转)Java中equals和==的区别

    java中的数据类型,可分为两类:  1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boolean    他们之间的比较,应用双等号( ...

  2. java中的==和equals的区别

    关于JAVA中的==和equals函数的区别 今天在研读Thinking in java 时注意到==和equals的区别,于是就通过查看JDK_API才读懂了他们的区别,于是将心得分享一下,望批评指 ...

  3. java中equals和==的区别 (转)

    java中equals和==的区别  值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中. ==操作比较的是两个变量的值是否相等,对于引 ...

  4. 【转】Java中equals和==的区别

    [转]Java中equals和==的区别 java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boole ...

  5. C#中 Equals和= =的区别

    C#中 Equals和= =的区别 前言:最近感觉技术进步实在是太慢,一直被游戏缠身不能自拔哈哈,但是游戏打多了真的是感觉整个人浮躁的不行,所以我现在要去游戏多写代码多看书,今天在博客园中看到一个前辈 ...

  6. C# 中 equals( ) 和 == 的区别和用法

    Equals: 下面的语句中,x.y 和 z 表示不为 null 的对象引用. * 除涉及浮点型的情况外,x.Equals(x) 都返回 true. * x.Equals(y) 返回与 y.Equal ...

  7. Java 中 Equals和==的区别(转)

    另外一篇参考: https://blog.csdn.net/striverli/article/details/52997927 在谈论equals和==的区别前,我们先简单介绍一下JVM中内存分配的 ...

  8. Java中equals和==的区别?为什么重写equals方法后,一定要重写hashCode方法?

    首先明确一点,equals是方法,==是操作符. 1. 如果比较的是基本数据类型: 只讨论==,因为equals是不存在的,因为java中基本数据类型不能调用method的. 2. 如果比较的是引用类 ...

  9. java中equals和==的区别详解

    java中的数据类型,可分为两类: 1.基本数据类型. byte,short,char,int,long,float,double,boolean这八大原始数据类型他们之间的比较,使用“==”,比较的 ...

随机推荐

  1. BZOJ 1497 最大获利

    最大权闭合子图 对于这个题,可以抽象成一个图论模型,如果我们把用户与其要求建立的中转站连边,获得的利益看成正权值,付出的代价看成负权值,我们可以发现,选取一个用户的时候,就相当于选取了一个闭合子图. ...

  2. jenkins运行脚本生成HTML报告时遇到的问题

    1.jenkins生成HTML报告 1)安装插件:HTML Publisher plugin 2)系统管理->插件管理->安装HTMLHTML Publisher plugin 2.job ...

  3. Treasure Hunting HDU - 3468

    题意: 输入一个n行m列的图 每次按字母顺序走最短路, 从一个字母走到下一个字母的过程中,只能拿走一个金子,求走完当前图中所有的字母后能拿到的金子的最大值 解析: bfs求最短路 对于一个金子如果 d ...

  4. 【XSY2753】Lcm 分治 FWT FFT 容斥

    题目描述 给你\(n,k\),要你选一些互不相同的正整数,满足这些数的\(lcm\)为\(n\),且这些数的和为\(k\)的倍数. 求选择的方案数.对\(232792561\)取模. \(n\leq ...

  5. Leetcode 167. 两数之和 II - 输入有序数组 By Python

    给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数. 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2. 说明: 返回的下标值 ...

  6. 集群概念Cluster

    系统扩展方式: scale up,向上扩展:提高主机性能等,质变: scale out,向外扩展:水平扩展,质不变量变: 集群类型: LB:Load Balancing 负载均衡集群: HA:High ...

  7. SP8791 DYNALCA - Dynamic LCA 解题报告

    SP8791 DYNALCA - Dynamic LCA 有一个森林最初由 \(n (1 \le n \le 100000)\) 个互不相连的点构成 你需要处理以下操作: link A B:添加从顶点 ...

  8. 老铁,告别postman,用pycharm来调接口,顺便把接口脚本也写了

    最近,一位同事在用postman调涉及到依赖的接口的时候 postman设置了环境变量,但是老是获取不到依赖接口返回的值,至于的啥原因呢,@#¥%……&*()! 其实,用pycharm一样可以 ...

  9. limits.conf文件工作原理

    1. limits.conf 描述 limits.conf文件实际是Linux PAM(插入式认证模块,Pluggable Authentication Modules)中 pam_limits.so ...

  10. 【POJ2230】Watchcow

    题目大意:给定一个 N 个点,M 条边的无向图,要求不重复地经过每条边两次,并且从 1 号节点出发最后回到 1 号节点,求一条路径. 题解:不重复地经过两次这个操作很容易地通过无向图的建边方式来实现, ...