这个问题风闻是至公司面试城市问的问题,以前不怎么了解,好奇心蛊惑我来研究一下
首先从值类型分析,先写几句简单的代码供测试用,二行语句输出的都是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,好长的一大段
1 private unsafe static bool EqualsHelper(String strA, String strB) 2 { 3 Contract.Requires(strA != null); 4 Contract.Requires(strB != null); 5 Contract.Requires(strA.Length == strB.Length); 6 //生存当前String长度 7 int length = strA.Length; 8 //固定住二个字符串的首字符地点 9 fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar) 10 { 11 //界说二个指针用来生存字符串首地点 12 char* a = ap; 13 char* b = bp; 14 //下面判断是否是AMD64位系统,我这不是就往下执行 15 // unroll the loop 16 #if AMD64 17 // for AMD64 bit platform we unroll by 12 and 18 // check 3 qword at a time. This is less code 19 // than the 32 bit case and is shorter 20 // pathlength 21 22 while (length >= 12) 23 { 24 if (*(long*)a != *(long*)b) return false; 25 if (*(long*)(a+4) != *(long*)(b+4)) return false; 26 if (*(long*)(a+8) != *(long*)(b+8)) return false; 27 a += 12; b += 12; length -= 12; 28 } 29 30 #else 31 //A段觉得是多余的,直接执行B段就完事 32 //判断字符串A长度是否大于10,为真的话每次读取四个字节进行对照 33 //如果不不异就直接返回false,最后指针向后移动10个字节,长度减少10 34 while (length >= 10) 35 { 36 if (*(int*)a != *(int*)b) return false; 37 if (*(int*)(a+2) != *(int*)(b+2)) return false; 38 if (*(int*)(a+4) != *(int*)(b+4)) return false; 39 if (*(int*)(a+6) != *(int*)(b+6)) return false; 40 if (*(int*)(a+8) != *(int*)(b+8)) return false; 41 a += 10; b += 10; length -= 10; 42 } 43 #endif 44 45 // This depends on the fact that the String objects are 46 // always zero terminated and that the terminating zero is not included 47 // in the length. For odd string sizes, the last compare will include 48 // the zero terminator. 49 50 //B段 51 //这里是前10个字节的匹配情况下,从+10开位置开始继续每四个字节的进行对照 52 //只要不匹配,跳出循环,那长度必定必定不为0, 这里break也是多余,直接return false 53 //如果所有字节都匹配,最终长度为0,跳出循环,返回真 54 while (length > 0) 55 { 56 if (*(int*)a != *(int*)b) break; 57 a += 2; b += 2; length -= 2; 58 } 59 60 return (length <= 0); 61 } 62 }
颠末漫长的分析可以得出结论,== 与Equals对照的是每个字符,而并不是对照的引用地点
尝尝自界说的引用类型,创建一个类.先写几句简单的代码供测试用,二行语句输出的都是false
说明自界说的引用类型 == 与Equals也是不异,对照的都是引用地点
结论就是不管是==还是Equals其功效都是不异的
当类型是值类型时,对照是数值
当类型是引用类型时,对照的是引用地点,除了String类型对照的是引用地点下的内容