在值类型中 ==和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,留==作为引用比较。
原文:https://www.cnblogs.com/kafeibuhuizui/p/10573478.html