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

首先从值类型分析,先写几句简单的代码供测试用,二行语句输出的都是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. Linux挖矿程序kworkerds分析

    0×00 背景概述 近日,同伴的一台Linux服务器中了kworkerds挖矿程序,随即对挖矿程序进行了处理与分析. 0×01服务器现状 进入服务器之后通过top命令,没有发现有占用CPU资源过高的进 ...

  2. java-int数据的溢出

    数据的溢出: 当整数的数据大小超出了可以表示的范围,而程序中又没有做数值范围的检查时, 这个整型变量所输出的值将发生紊乱,且不是预期的运行结果. 01 //  整数值如果超出了自己所可以表示范围的最大 ...

  3. Python OpenCV 显示图片,图片分类

    def divide_image(path,g_path1,g_path0): img_lst = os.listdir(path) for i in img_lst: print('类别1,类别0' ...

  4. Laravel服务容器的绑定与解析

    本篇文章给大家带来的内容是关于Laravel服务容器的绑定与解析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 前言   老实说,第一次老大让我看laravel框架手册的那天早上,我 ...

  5. SWIG 3 中文手册——1. 前言

    目录 1 前言 1.1 引言 1.2 SWIG 版本 1.3 SWIG 许可证 1.4 SWIG 资源 1.5 前提要求 1.6 本手册的组织构成 1.7 如何避免阅读手册 1.8 向后兼容 1.9 ...

  6. rem与em的使用和区别

    区别是:浏览器根据谁来转化成px值. 当使用rem单位,转换为像素大小取决于根元素的字体大小,即HTML元素的字体大小. 有一个比较普遍的误解,认为em单位是相对于父元素的字体大小.事实上,根据W3C ...

  7. AngularJS简介与四大特征

    1.1 AngularJS简介 AngularJS  诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优秀的前端JS框架,已经被用于Google的多款产品当中.A ...

  8. centos7.x下环境搭建(三)—nodejs安装

    有3种方式可以安装nodejs yum安装 源码包安装 nvm方式安装 一.方式1:yum安装 这里我们指定安装8.x以上的版本 # curl --silent --location https:// ...

  9. 『optimization 动态规划』

    optimization Description \(visit\_world\) 发现有些优化问题可以用很平凡的技巧解决,所以他给你分享了这样一道题: 现在有一个长度为N的整数序列\(\{a_i\} ...

  10. 补习系列(12)-springboot 与邮件发送【华为云技术分享】

    目录 一.邮件协议 关于数据传输 二.SpringBoot 与邮件 A. 添加依赖 B. 配置文件 C. 发送文本邮件 D.发送附件 E. 发送Html邮件 三.CID与图片 参考文档 一.邮件协议 ...