• C#中Equals 与== 的区别


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

    首先从值类型分析,先写几句简单的代码供测试用,二行语句输出的都是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类型比较的是引用地址下的内容

  • 相关阅读:
    filter
    验证
    HTML5 canvas 内部元素事件响应
    canvas 椭圆
    计算2点角度
    复制pdf文字出来是乱码的一种可能的解决方案
    LaTeX Pdf to Word
    论文题录导入导出的困惑
    公式测试
    [LaTex]Visio文件转EPS文件[转]
  • 原文地址:https://www.cnblogs.com/fzxiaoyi/p/8495639.html
Copyright © 2020-2023  润新知