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 = ;
int j = ;
Console.WriteLine(i == j);//值类型比较代数值 输出True int m = ;
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 = ;
int j = ;
Console.WriteLine(i.Equals(j));//值类型比较 输出True int m = ;
double n = 6.0;
Console.WriteLine(m.Equals(n));//类型不会自动转换并比较数值 输出False object obj1 = new object();
object obj2 = new object();
Console.WriteLine(obj2.Equals(obj1));//引用类型比较 输出False
Console.WriteLine(obj2.Equals(string.Empty));//输出False,比较量对象的类型不同直接返回False

Equals比较

  3.3 ReferenceEquals 

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

            int i = ;
int j = ;
Console.WriteLine(object.ReferenceEquals(i, j));//输出False int m = ;
double n = 6.0;
Console.WriteLine(object.ReferenceEquals(m, n));//输出False object obj1 = new object();
object obj2 = new object();
Console.WriteLine(object.ReferenceEquals(obj1, obj2));//输出False

ReferenceEquals比较

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.html
http://www.cnblogs.com/zagelover/articles/2741409.html

C#扫盲之:==/Equals /ReferenceEquals 异同的总结,相等性你真的知道吗?的更多相关文章

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

    1.前言 == Equals ReferenceEquals 三个相等性测试,是.NET提供给程序员使用的三个方法,他们之间有什么联系和区别,你真的仔细研究过?虽然之前也多多少少知道一点,但是有时候又 ...

  2. == Equals ReferenceEquals 比较

    == 为操作符 ReferenceEquals和Equals为函数 ========================================================= Referenc ...

  3. ==和equals的异同

    == 和 Equals 的区别 1. == 是一个运算符. 2.Equals则是string对象的方法,可以.(点)出来. 我们比较无非就是这两种 1.基本数据类型比较 2.引用对象比较 1.基本数据 ...

  4. ==、Equals 、ReferenceEquals它们的异同

    链接 string foobar = "foobar"; string foobar2 = new StringBuilder().Append("foo"). ...

  5. C#中==、Equals、ReferenceEquals的区别

    原文链接:http://www.studyofnet.com/news/1188.html 本文导读: C#中Equals , == , ReferenceEquals都可以用于判断两个对象的个体是不 ...

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

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

  7. C# == 和 Equals

    先看一下解释 msdn对于 == 的解释: 对于预定义的值类型,如果操作数的值相等,则相等运算符 (==) 返回 true,否则返回 false. 对于 string 以外的引用类型,如果两个操作数引 ...

  8. NET-知识点:C#中Equals和==比较

    第一.相等性比较 其实这个问题的的本质就是C#的相等比较,相等比较可以分两类: 1.引用相等性,引用相等性指两个对象引用均引用同一基础对象. 2.值相等性,值相等性指两个对象包含相同的一个或多个值,其 ...

  9. 浅析Object基类提供的Equals方法

    当我们去查看object.cs源代码文件的时候,会发现object基类提供了三种判断相等性的方法.弄清楚每种方法存在的原因,也就是具体解决了什么问题,对我们理解.net判断对象相等性的逻辑很有帮助,下 ...

随机推荐

  1. 【暑假】[深入动态规划]UVa 10618 Fun Game

    UVa 10618 Fun Game 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36035 思路:   一圈人围坐 ...

  2. 用Python写的批量文件重命名

      有些时候下载图片或其他文件,文件名都怪怪的,可选的办法是下载一个文件批量重命名的软件.当然,如果想自己'DIY'一把的话编个Python脚本最好不过了. 下面的代码实现的对指定类型的文件进行批量重 ...

  3. EXCEL 操作

    1.为几万行数据加序号 先在A1,A2分别输入1,2,选中A1:A2,双击A2右下角那个小方块. 数据有多少行就会自动填充多少行(要求:B列数据连续) 2.统计一列中单元格的值等于某个值的单元格的个数 ...

  4. hive 中出现struct 结构化的问题

    如果你使用udf,udaf,udtf中的某一个并且查询日志中出现如下之类的struct错误 java.lang.RuntimeException: Error in configuring objec ...

  5. 关于main()和_tmain()

    1.两者的共同点 int _tmain(int argc, _TCHAR* argv[])    和  int main(int argc, char* argv[])  ,两者都是程序的主函数,两者 ...

  6. ABAP报表程序编写规范 .

    一.              程序的结构: 典型的ABAP报表程序是由多个代码区域组成,各代码区的存放位置以下列顺序为准,具体格式如下: *----------------------------- ...

  7. [iOS基础控件 - 5.3] 电台APP可滚动主界面(UIScrollView制作)

    A.功能 1.上下可滚动的电台 2 x n 的图标集 2.顶部半透明标题 3.底部半透明功能按钮   B.实现思路 1.设置图标.启动画面       2.拖入UIScrollView,设置背景色 ( ...

  8. 转载 C#匿名函数 委托和Lambda表达式

    转载原出处: http://blog.csdn.net/honantic/article/details/46331875 匿名函数 匿名函数(Anonymous Function)是表示“内联”方法 ...

  9. CC_CALLBACK原理及应用

    http://my.oschina.net/u/555701/blog/219844 c++ 11 基础 :     std::function 类模版 std::function是一种通用.多态的函 ...

  10. 按要求编写一个Java应用程序: (1)定义一个类,描述一个矩形,包含有长、宽两种属性,和计算面积方法。 (2)编写一个类,继承自矩形类,同时该类描述长方体,具有长、宽、高属性, 和计算体积的方法。 (3)编写一个测试类,对以上两个类进行测试,创建一个长方体,定义其长、 宽、高,输出其底面积和体积。

    package jvxing; public class Jvxing { //成员变量 private double width; private double chang; public doub ...