C# 对象相等性判断和同一性判断
在日常开发中经常需要编写代码比较不同的对象。例如,有时需要将对象都放到一个集合中,并编写代码对集合中的对象进行排序、搜索或者比较。
System.Object类有两个Equals方法,如下:
1、实例Equals方法(可重写),代码如下:
public virtual bool equals(object obj) => RuntimeHelpers.Equals(this, obj)
再看看RuntimeHelpers.Equlas里面调的是什么方法,代码如下:
[MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical]
public static extern bool Equals(object o1, object o2);
ok,这里的extern关键字告诉你,接下来的不用你考虑了!
2、静态方法Equals方法,代码如下:
public static bool Equals(object objA,object objB)=>
((objA==objB) || (((objA!=null) && (objB!=null)) && objA.Equals(objB)))
继续深入解析代码,发现objA.Equals调用了上面的实例Equals方法.其实就是在实例Equals方法的基础上做了非空判断.然后方法做了静态化.
到这里源码解析完毕,由于到extern这一步解析不下去了(博主实力有限),如有知道的请告知!万分感谢!
由于类型能够重写Equals方法,所以Equals方法的逻辑远比想象的要复杂.下面来举几个例子:
1、由于类型能够重写Equals方法,所以不能使用它来测试同一性,为了解决这个问题,Object类型提供了ReferenceEquals方法来比较两个对象的同一性,ReferenceEquals代码如下:
public static bool ReferenceEquals(object objA,object objB)=>(objA==objB)
注:判断两个对象的"同一性"不应该使用C#的==操作符(除非将两个操作符进行装箱转换为Object),因为某个操作数可能重载了==操作符
2、System.ValueType(所有值类型的基类)就重写了Object的Equals方法,并对两个对象进行了正确的值相等检查而不是同一性检查.代码如下:
public bool Equals(uint obj)=>(this == obj);
==操作符进行的值检查.
ValueType.Equals内部会进行一下操作:
1、如果obj实参为null,就返回false;
2、如果this和obj引用的是不同的对象,返回false;
3、针对类型定义的每个实例字段,都将this对象中的值与obj对象中的值进行比较(通过调用对象的Equals方法)。任何字段不相等,就返回false.
4、返回true,ValueType的Equals方法不掉用Object的Equals方法.
上述3步骤,是通过反射实现,由于CLR的反射机制效率不高,所以在定义自己的值类型的时候,应重写Equals方法来提供自己的实现,从而提高自己类型进行值类型比较时的性能.注:自己的实现不用调用base.Equals().
当我们定义自己的类型时,重写的Equals方法要符合下面几个特性:
1、Equals必须自反 x.Equals(x)肯定返回true.
2、Equlas必须对称 x.Equals(y)和y.Equals(x)必须返回相同的值
3、Equals必须可传递 x.Equals(y)返回true,y.Equals(z)返回true则x.Equals(z)也必须返回true.
4、Equals必须一致,比较的两个值不变,Equals返回值(true或false)也不能变
如果实现的Equals方法不符合上述特性,应用程序就会行为失常.
重写Equals方法必须做以下几件事
1、让类型实现System.IEquatable<T>接口的Equals方法
这个泛型接口允许定义类型安全的Equals方法,通常实现的Equals方法应获取一个Object参数,以便在内部调用类型安全的Equals方法.
2、重载==和!=操作符方法
通常应实现这些操作符方法,在内部调用类型安全的Equals方法.
C# 对象相等性判断和同一性判断的更多相关文章
- Js判断对象是否为空,Js判断字符串是否为空
Js判断对象是否为空,Js判断字符串是否为空,JS检查字符串是否为空字符串 >>>>>>>>>>>>>>>&g ...
- 在Map对象中获取属性,注意判断为空
在Map对象中获取属性,注意判断为空 public static void main(String[] args) { Map map = new HashMap(); Integer i = (In ...
- c# 对象相等性和同一性
一:对象相等性和同一性 System.Object提供了名为Equals的虚方法,作用是在两个对象包含相同值的前提下返回true,内部实现 public class Object { public v ...
- js数据类型判断和数组判断
这么基础的东西实在不应该再记录了,不过嘛,温故知新~就先从数据类型开始吧 js六大数据类型:number.string.object.Boolean.null.undefined string: 由单 ...
- 判断逻辑 先判断协议字段返回,再判断业务返回,最后判断交易状态 API密钥
[微信支付]微信小程序支付开发者文档 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_1 协议规则 商户接入微信支付, ...
- [改善Java代码]用偶判断,不用奇判断
建议21: 用偶判断,不用奇判断 public class Client { public static void main(String[] args) { Scanner in = new Sca ...
- 判断DataTale中判断某个字段中包含某个数据
// <summary> /// 判断DataTale中判断某个字段中包含某个数据 /// </summary> /// <param name="dt&quo ...
- 快学Scala 第十三课 (类型层级,对象相等性)
Scala 类型层级: 对象相等性: 和Java一样要重写equals方法和hashcode方法 class Student(val id: Int, val name: String) { over ...
- java 对象、集合的非空判断
自我总结,有什么不到位的地方,请各位纠正补充,感激不尽! 目的:使程序更严谨 ***对象验证是否不为空: if( null != obj ) ***List验证不为空:if( null != lis ...
随机推荐
- MFC框架仿真<二>
- (转)SQL Server 2008无法修改表的解决办法
转自:http://www.soaspx.com/dotnet/sql/mssql/sql2008/sqlserver2008_20121010_9683.html 在SQL Server 2008 ...
- [翻译] Using Custom Functions in a Report 在报表中使用自己义函数
Using Custom Functions in a Report 在报表中使用自己义函数 FastReport has a large number of built-in standard ...
- ABP 基础设施层——集成 NHibernate
本文翻译自ABP的官方教程<NHibernate Integration>,地址为:http://aspnetboilerplate.com/Pages/Documents/NHibern ...
- asp.net MVC 统计在线人数功能实现
今天开发一个设计一个统计在线人数的统计.实现方式是在MVC 中,用户次执行一个Action请求完成后,向数据表中插入一条用户心跳记录,统计在线人数则是根据该记录,30分钟内有记录的用户则为在线状态. ...
- Stm32 ADC学习
stm32 ADC 简介 stm32的ADC是 12位逐次逼近型 模拟数字转换器;它包括18个通道,可以用来测量16个外部通道和2个内部通道.ADC转换的结果存放在16位数据寄存器(ADC规则数据寄存 ...
- 用MVC5+EF6+WebApi 做一个考试功能(六) 仓储模式 打造EF通用仓储类
前言 年底工作比较忙,年度总结还没写,项目要上线,回老家过年各种准备.尤其是给长辈给侄子侄女准备礼物头都大了. 原来想年前先出一版能用的,我看有点悬了,尽量先把大体功能弄出来,扔掉一些,保证能考试,然 ...
- BootStrap 4正式版发布(原文翻译)
原文链接:http://blog.getbootstrap.com/2018/01/18/bootstrap-4/ 关于Bootstrap 什么是Bootstrap Bootstrap,来自 Twit ...
- onsrcoll和scrollTop兼容与实现
对于onscroll事件的支持 各浏览器 document.document.body.document.documentElement 对象的 onscroll 事件的支持存在差异. 所谓的支持性存 ...
- 使用math.js进行javascript精确计算
javascript进行浮点运算会有尾差,比如算个0.1+0.7试试,得到的不是0.8 .这个问题可以使用math.js解决. Math.js是一款开源的JavaScript和Node.js数学库,用 ...