l  Equality:如果两个对象是相同的类型,并且它们各自带有相同和等值的属性。(They are instances of the same type and if each of the fields in one object matches the values of the fields in the other object) 
Equality必须满足三个必要条件:reflexive, symmetrics, and transitive
reflexive: 自身相等,及a==a 是永远成立的;
symmetrics: 对象性,及a==b成立那么b==a 也成立;
transitive: 传递性,及a==b, b==c成立那么a==c 也成立。

l  Identity:两个对象必须相等(意味着他们共享同一块内存区域)(The two objects have the same values. – Two objects are identical if they share an address in memory)

CLR提供了至少四种方法来判断两个对象的等价性:

1.      Public static bool ReferenceEquals(object left, object right);

2.      Public static bool Equals(object left, object right);

3.      Public virtual bool Equals(object right);

4.      Public static bool operator==(MyClass left, MyClass right);

ReferenceEquals方法总是用来判断两个对象的Identity的,不管是针对值类型还是引用类型。所以针对值类型,调用该方法总是会返回false,因为值类型作为这个方法的参数时会进行装箱操作。

静态的Equals方法提供了判断两个对象的Equality能力,在其实现的内部,调用了上述第三个虚拟的Equals方法。和ReferenceEquals一样,它们已经具备从底层判断两个对象的能力,我们从来不会覆写这两个方法。

实例Equals方法也是用来区分两个对象的Equality的。

l  对于引用类型的对象,它和ReferenceEquals方法几乎是一样的。(因为判断两个引用类型是否的Equality往往从Identity上就可以区分)

l  而值类型的对象,我们不仅要判断他们具有相同的对象类型,还要判断他们的值相等。值类型从System.ValueType继承而来,ValueType已经重写了Object.Equals()方法,本来已经可以用来满足这些要求的。但是ValueType.Equals()方法不是很有效,因为它必须要通过反射,在不知道具体的派生类型中,完成对它们所含有成员变量的值的比较。因此,建议在我们实现一个值类型的数据结构时,同时重写ValueType.Equals()方法。

l  然而我们再回头看看引用类型,有时两个引用类型的对象往往被用来进行类似值类型的比较,比如:String类型,它虽然是引用类型,但它也重写了Equals方法,因为我们拿它来判断两个string是否相同(Equality),实际是希望判断它们是否具有相同的内容,这是一个value semantics。因此,我们建议在考虑实现一个用作值语义环境下的引用类型时候,也重写基类的Object.Equals()方法。

注:请参考MDSN或其它相关文档,如何实现Equals方法的重写。

上面的图示给了很好的例子来区分Equals和ReferenceEquals方法,被用来做Equility和Identity判断的区别。

==运算符是可由类重载的运算符,它也是用来判断恒等的。
对于未重载==的引用类型,会比较两个引用类型是否引用同一个对象。这跟引用类型的Equals()方法是一样的。

对于未重载==的值类型,该运算符会比较这两个值是否"按位"相等,即是否这两个值中的每个字段都相等。和Equals方法一样,推荐在自定义值类型中,也要重载==运算符,因为也存在反射在效率上的影响。

==运算符和Equals方法的区别在于多态表现上。Equals方法是重写,而==运算符是被重载。这意味着除非编译器知道调用具体的重载版本,否则它只是调用未重载的==版本。

C#中的类型相等与恒等(Equality & Identity)的更多相关文章

  1. 详解Java 8中Stream类型的“懒”加载

    在进入正题之前,我们需要先引入Java 8中Stream类型的两个很重要的操作: 中间和终结操作(Intermediate and Terminal Operation) Stream类型有两种类型的 ...

  2. SQL 中不同类型的表连接

    http://www.linuxidc.com/Linux/2012-08/68035.htm 1.简介 在关系型数据库中,join操作是将不同的表中的数据联合在一起时非常通用的一种做法.首先让我们看 ...

  3. Object-C中动态类型对象相关操作汇总

    Object-C(以后简称OC)中有id类型,相对于明确定义类型的静态类型,称为动态类型. 使用动态类型,配合多态(不同类型拥有同名方法),动态绑定(运行时决定实际调用的方法)可以将很多判断延迟到运行 ...

  4. MYSQL中 ENUM 类型

    MYSQL中 ENUM 类型的详细解释 ENUM类型 ENUM 是一个字符串对象,其值通常选自一个允许值列表中,该列表在表创建时的列规格说明中被明确地列举. 在下列某些情况下,值也可以是空串(&quo ...

  5. 第66课 C++中的类型识别

    1. 类型识别 (1)在面向对象中可能出现下面的情况 ①基类指针指向子类对象 ②基类引用成为子类对象的别名 ▲静态类型——变量(对象)自身的类型(定义变量类型时类型或参数类型) ▲动态类型——指针(引 ...

  6. 【翻译自nikic大神】PHP中原生类型的方法

    引言 第一次,翻译别人的文章,用四级英语的水平来翻译~~囧,可能有很多不太恰当的地方,尽管拍砖(有些地方实在想不到恰当的翻译,我同时贴出了原文和自己很low的翻译). 翻译这篇文章用了我3个晚上一个中 ...

  7. SQL批量更新数据库中所有用户数据表中字段类型为tinyint为int

    --SQL批量更新数据库中所有用户数据表中字段类型为tinyint为int --关键说明:--1.从系统表syscolumns中的查询所有xtype='48'的记录得到类型为[tinyint]的字段- ...

  8. NET中的类型和装箱/拆箱原理

    谈到装箱拆箱,DebugLZQ相信给位园子里的博友一定可以娓娓道来,大概的意思就是值类型和引用类型的相互转换呗---值类型到引用类型叫装箱,反之则叫拆箱.这当然没有问题,可是你只知道这么多,那么Deb ...

  9. Scala 深入浅出实战经典 第54讲:Scala中复合类型实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

随机推荐

  1. 06.yield

    Thread.yield()方法的作用:暂停当前正在执行的线程,并执行其他线程.(可能没有效果) yield()让当前正在运行的线程回到可运行状态,以允许具有相同优先级的其他线程获得运行的机会.因此, ...

  2. OpenCV常用基本处理函数(4)简单变换,阈值等

    几何变换 缩放 img=cv2.imread('messi5.jpg') # 下面的 None 本应该是输出图像的尺寸,但是因为后边我们设置了缩放因子 # 因此这里为 None res=cv2.res ...

  3. API登录验证

    客户端 客户端token加在header头中,通过request发送给服务端 服务端 服务端 通过request.META.get(HTTP_TOKEN)拿到客户端传来的token 然后与服务器事先存 ...

  4. 【Flutter学习】基本组件之TabBar顶部导航

    一,概述 TabBar,是材料设计(Material design)中很常用的一种横向标签页.在Android原生开发中,我们常用ViewPage或者一些常用的标签页开源库,来实现并行界面的横向滑动展 ...

  5. Database基础(二):MySQL索引创建与删除、 MySQL存储引擎的配置

    一.MySQL索引创建与删除 目标: 本案例要求熟悉MySQL索引的类型及操作方法,主要练习以下任务: 普通索引.唯一索引.主键索引的创建/删除 自增主键索引的创建/删除 建立员工表yg.工资表gz, ...

  6. How do I force my .NET application to run as administrator?

    How do I force my .NET application to run as administrator? You'll want to modify the manifest that ...

  7. python如何读写EXCEL文档 (有助于自动化的参数化,用的方法是XLRD,XLWT)

    读EXCEL: import xlrd 例1, data=xlrd.open("E:\egg.xls")     # 打开xls文件 table=data.sheets()[0] ...

  8. flex 布局 实现三点筛子

    实现麻将中三点筛子:效果如下图 具体实现代码: html代码: <div class="box"> <div class="item"> ...

  9. 52、saleforce 导入csv文件

    Load Data Using the Custom Object Import Wizard 1. 2. 3. 4. 5. 6.然后就导入成功了

  10. 在不打开excel的情况下用python执行excel

    import win32com.client import time path = r'absolute dir' #比如填文件的绝对路径,比如d:/file/stock.xlsx xl = win3 ...