这个问题听说是大公司面试都会问的问题,以前不怎么了解,好奇心勾引我来研究一下

首先从值类型分析,先写几句简单的代码供测试用,二行语句输出的都是true,

说明==与Equals功能是相同的, 判断的都是数值.

进入int内部查看下

重写Equals(object obj)

重载Equals(int obj)

可以看得出int.Equals是以自身与目标值进行比较,跟==是相同的功能.

为了确定下其它值类型Equlas与==是否也是一样,再选一个float类型进行查看

其次开始分析下所有类型的基类Object,也写几句简单代码进行测试,二行语句输出的都是false

说明==与Equals功能是相同的, 判断的都是引用地址

也是进入object内部查看下

继续进入RuntimeHelpers中查找Equals

发现这里没有代码了,点击左边的按钮返回到object.Equals

接着分析下引用类型中的String,也写几句简单代码进行测试,二行语句输出的都是true

这就有意思了,为啥输出结果都是true呢

按常规理解来说

使用new关键字在托管堆中申请内存存储string类型数据,然后返回内存地址赋值给

变量,使之指向托管堆中的string类型的对象

每次实例化的对象在托管堆中的地址都不相同才对。

带着疑问还是进入String内部进行一探究尽

可以看到内部对运算符==进行了重载,== 和 Equals也是相同的功能

继续查看Equals

进入EqualsHelper,好长的一大段

       private unsafe static bool EqualsHelper(String strA, String strB)
{
Contract.Requires(strA != null);
Contract.Requires(strB != null);
Contract.Requires(strA.Length == strB.Length);
//保存当前String长度
int length = strA.Length;
//固定住二个字符串的首字符地址
fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)
{
//定义二个指针用来保存字符串首地址
char* a = ap;
char* b = bp;
//下面判断是否是AMD64位系统,我这不是就往下执行
// unroll the loop
#if AMD64
// for AMD64 bit platform we unroll by 12 and
// check 3 qword at a time. This is less code
// than the 32 bit case and is shorter
// pathlength while (length >= )
{
if (*(long*)a != *(long*)b) return false;
if (*(long*)(a+) != *(long*)(b+)) return false;
if (*(long*)(a+) != *(long*)(b+)) return false;
a += ; b += ; length -= ;
} #else
//A段感觉是多余的,直接执行B段就完事
//判断字符串A长度是否大于10,为真的话每次读取四个字节进行比较
//如果不相同就直接返回false,最后指针向后移动10个字节,长度减少10
while (length >= )
{
if (*(int*)a != *(int*)b) return false;
if (*(int*)(a+) != *(int*)(b+)) return false;
if (*(int*)(a+) != *(int*)(b+)) return false;
if (*(int*)(a+) != *(int*)(b+)) return false;
if (*(int*)(a+) != *(int*)(b+)) return false;
a += ; b += ; length -= ;
}
#endif // This depends on the fact that the String objects are
// always zero terminated and that the terminating zero is not included
// in the length. For odd string sizes, the last compare will include
// the zero terminator. //B段
//这里是前10个字节的匹配情况下,从+10开位置开始继续每四个字节的进行比较
//只要不匹配,跳出循环,那长度肯定肯定不为0, 这里break也是多余,直接return false
//如果所有字节都匹配,最终长度为0,跳出循环,返回真
while (length > )
{
if (*(int*)a != *(int*)b) break;
a += ; b += ; length -= ;
} return (length <= );
}
}

经过漫长的分析可以得出结论,== 与Equals比较的是每个字符,而并不是比较的引用地址

试试自定义的引用类型,创建一个类.先写几句简单的代码供测试用,二行语句输出的都是false

说明自定义的引用类型 == 与Equals也是相同,比较的都是引用地址

结论就是不管是==还是Equals其结果都是相同的

当类型是值类型时,比较是数值

当类型是引用类型时,比较的是引用地址,除了String类型比较的是引用地址下的内容

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. C#中equals和==的区别有哪些

    本文导读:C# 中==是用来判断变量的值是否相等,相等返回true,不相等返回false.Equals是用来判断两个对象(除string类型外)是否相等,相等的 条件是:值,地址,引用全相等,因为St ...

  10. java中equals()和==的区别

    java中的数据类型 基础数据类型 基础数据类型有byte.short.char.int.long.float.double.bool.String.除了 String 会比较地址,其它的基础类型的比 ...

随机推荐

  1. ASP.NET的MVC请求处理流程

    1.用户打开浏览器,在地址栏输入某个网址的URL并回车,浏览器便开始像该URL指定的服务器发起HTTP请求 .2.服务器的网站服务系统(IIS)接收到该请求,先检查自己是否认识该类请求,如果认识就直接 ...

  2. sqlyog -------- 安装

    SQLyog是RDBMS MySQL的GUI工具.在从Windows Vista到Windows 10的Windows平台上运行,使用Wine环境,还使其可以在Linux和各种Unix(包括macOS ...

  3. k8s网络原理

    https://blog.csdn.net/watermelonbig/article/details/80646988 k8s中,每个 Pod 都有一个独立的 IP 地址,所有 Pod 在一个网络空 ...

  4. 使用 Python 获取 Windows 聚焦图片

    Windows 聚焦图片会定期更新,拿来做壁纸不错,它的目录是: %localappdata%\Packages\Microsoft.Windows.ContentDeliveryManager_cw ...

  5. thinkphp3.2.3使用formdata的多文件上传

    使用formdata的多文件上传  废话少说 直接上代码 1 JS部分 //选择文件后的处理 function handleFileSelect() { var exerciseid=$(" ...

  6. lombok的@Accessors注解3个属性说明

    https://www.cnblogs.com/kelelipeng/p/11326936.html https://www.cnblogs.com/kelelipeng/p/11326621.htm ...

  7. HBase统计表行数(RowCount)的四种方法

    背景:对于其他数据存储系统来说,统计表的行数是再基本不过的操作了,一般实现都非常简单:但对于HBase这种key-value存储结构的列式数据库,统计 RowCount 的方法却有好几种不同的花样,并 ...

  8. 排序算法Java代码实现(五)—— 快速排序

    本篇内容: 快速排序 快速排序 算法思想: 通过一趟排序将要排序的数据分割成独立的两部分, 其中一部分的所有数据都比另外一部分的所有数据都要小, 然后再按此方法对这两部分数据分别进行快速排序, 整个排 ...

  9. vertx 异步编程指南 step8-使用RxJava进行反应式编程

    vertx 异步编程指南 step8-使用RxJava进行反应式编程 2018-04-23 13:15:32 zyydecsdn 阅读数 1212  收藏 更多 分类专栏: vertx   到目前为止 ...

  10. Qt实现表格树控件-支持多级表头

    目录 一.概述 二.效果展示 三.实现方式 四.多级表头 1.数据源 2.表格 3.QStyledItemDelegate绘制代理 五.测试代码 六.相关文章 原文链接:Qt实现表格树控件-支持多级表 ...