首页 > 其他 > 详细

2019.03.21 读书笔记 ==与Equals

时间:2019-03-21 18:35:33      阅读:166      评论:0      收藏:0      [点我收藏+]

在值类型中 ==和equals是一样的效果

在引用类型中 ==是比较引用,equals是比较值(不过自定义类,都是不相等的,只有在一种情况下是相等的,object装箱操作后,== 是false,Equals是true)

源码:

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

public virtual bool Equals(object obj)
{
    return RuntimeHelpers.Equals(this, obj);
}
即:equals(a,b)是先比较==,再比较值

凡是都有例外:string
string 重写了==运算符
public static bool operator ==(string a, string b)
{
    return Equals(a, b);
}
另外string也重写了Equals,走自己的比较方式:
public override bool Equals(object obj)
{
    if (this == null)
    {
        throw new NullReferenceException();
    }
    string strB = obj as string;
    if (strB == null)
    {
        return false;
    }
    if (this == obj)
    {
        return true;
    }
    if (this.Length != strB.Length)
    {
        return false;
    }
    return EqualsHelper(this, strB);
}


[SecuritySafeCritical, ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
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);
        }
    }
}
所以string只有值的比较,而且根据string的不可修改性,地址也是一样的。

在自定义类中,都可以对==和Equals重写,不过重写==必须重写!=, 否则报错,重写Equals建议重写gethascode,否则容易bug,针对于他们都能重写,Object提供了referenceequsls(),作为地址比较。
结论:
==和Equals的区别只有在装箱操作下,才会出现 == 是false Equals是 true,自定义类需要重写,建议重写Equals,留==作为引用比较。
 

2019.03.21 读书笔记 ==与Equals

原文:https://www.cnblogs.com/kafeibuhuizui/p/10573478.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!