zoukankan      html  css  js  c++  java
  • C#中 Equals和= =的区别

    C#中 Equals和= =的区别

    前言:最近感觉技术进步实在是太慢,一直被游戏缠身不能自拔哈哈,但是游戏打多了真的是感觉整个人浮躁的不行,所以我现在要去游戏多写代码多看书,今天在博客园中看到一个前辈去阿里面试的面试题,由浅入深的问了很多问题,所以我想这就是个契机,可以通过答题来学习知识让自己进步,闲话少说,我们正式开始

    0.复习堆栈知识

    因为要通过引用类型和值类型分情况讨论,所以对C#中堆栈知识的复习还是有必要的
    简单说结论:
      1·栈通常保存着我们代码执行的步骤,而堆上存放的则多是对象,数据等。
      2·值类型存放在栈上,引用类型存放在堆上,但是会在栈中生成一个指针。
      3·一个值类型被声明在一个方法体外并且在一个引用类型中,那它就会在堆上进行分配。

    1·分情况讨论

    在C#中,讨论这个问题要分三种情况

    • 值类型
    • 引用类型
    • String 字符串类型

    1.1值类型

    在值类型中,Equals都是通过==来实现的,类似于:

    public override bool Equals(object obj)
    {
        return ((obj is bool) && (this == ((bool) obj)));
    }
    

    所以在值类型中,Equals和==其实是完全一样的东西。

    1.2引用类型

    本质上来说,Equals都是集成自Object的Equals方法,通过反编译,可以看到Equals内部的逻辑,即:引用相同返回true,或者两个对象都不为空的情况下,内部值相同,也返回true

    public static bool Equals(object objA, object objB)
    {
        return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB)));
    }
    

    所以在值类型中,==是判断引用是否相同,而Equals判断内部值是否相同,当然如果引用相同内部值肯定也相同。

    1.3 String字符串类型

    字符串类型比较特殊,是因为在string类的内部对Equals和==两个方法都进行了重写,是的你没看错,两个都重写,所以很特殊

    public static bool operator ==(string a, string b)
    {
        return Equals(a, b);
    }
    
    public static bool Equals(string a, string b)
    {
        if (a == b)
        {
            return true;
        }
        if ((a == null) || (b == null))
        {
            return false;
        }
        if (a.Length != b.Length)
        {
            return false;
        }
        return EqualsHelper(a, b);
    }
    

    可以看到最后全部都定位到了EqualsHelper这个方法里面,所以在string里面,Equals和==的意义是相同的,全都是表示判断string的内部内容是否相同。(EqualsHelper方法的代码在文末)

    结语和总结

    • ==判断引用是否相同
    • Equals判断内部值是否相同
    • 不同情形下,具体情况稍有差别

    用了一整个晚上的时间把这个知识梳理研究明白,感觉时间过得很慢,也过得挺有意义的,还复习了markdown的语法,希望这是我改变自己生活的一个好的开始,预告下一篇文章的主题是:“什么时候捕获异常,什么时候抛出异常”

    private static unsafe bool EqualsHelper(string strA, string strB)
    {
        int length = strA.Length;
        fixed (char* chRef = &strA.m_firstChar)
        {
            fixed (char* chRef2 = &strB.m_firstChar)
            {
                char* chPtr = chRef;
                char* chPtr2 = chRef2;
                while (length >= 10)
                {
                    if (*(((int*) chPtr)) != *(((int*) chPtr2)))
                    {
                        return false;
                    }
                    if (*(((int*) (chPtr + 2))) != *(((int*) (chPtr2 + 2))))
                    {
                        return false;
                    }
                    if (*(((int*) (chPtr + 4))) != *(((int*) (chPtr2 + 4))))
                    {
                        return false;
                    }
                    if (*(((int*) (chPtr + 6))) != *(((int*) (chPtr2 + 6))))
                    {
                        return false;
                    }
                    if (*(((int*) (chPtr + 8))) != *(((int*) (chPtr2 + 8))))
                    {
                        return false;
                    }
                    chPtr += 10;
                    chPtr2 += 10;
                    length -= 10;
                }
                while (length > 0)
                {
                    if (*(((int*) chPtr)) != *(((int*) chPtr2)))
                    {
                        break;
                    }
                    chPtr += 2;
                    chPtr2 += 2;
                    length -= 2;
                }
                return (length <= 0);
            }
        }
    }
    
    
  • 相关阅读:
    leetcode二叉树相同的树
    leetcode二叉树中序遍历
    leetcode二叉树前序遍历
    leetcode数组中级Lc287.寻找重复数
    概要设计说明书
    leetcode二叉树对称二叉树
    小数点处理详解:切舍、切上、四舍五入
    C++多态的两种使用方式
    让Ogre的资源管理器为我们服务
    地形纹理Splatting技术(翻译)
  • 原文地址:https://www.cnblogs.com/codersun/p/6828277.html
Copyright © 2011-2022 走看看