這個段子是從MSDN上摘下來的,昨天給朋友調BUG才發現的,記錄+分享一下。
Equals 方法只是在 System.Object 中定義的一個虛擬方法,它由任何選擇執行該任務的類所重寫。== 運算子是一個可由類重載的運算子,該類通常具有恒等行為。
對於未重載 == 的參考型別,該運算子會比較兩個參考型別是否引用同一對象,而這恰好是 System.Object 中的 Equals 實現所做的工作。
對於未重載 == 的實值型別,該運算子會比較這兩個值是否"按位"相等,即是否這兩個值中的每個欄位都相等。當您對實值型別調用 Equals 時,仍然會發生這一情況,但這一次,該實現是由 ValueType 提供的,並且使用反射進行比較,從而使比較速度位元定於類型的實現慢很多。
到此為止,二者是如此類似。二者之間的主要區別是多態。運算子被重載而不是被重寫,這意味著除非編譯器知道調用更為具體的版本,否則它只是調用恒等版本。為闡明這一點,請看下面這個樣本:
using System;
public class Test
{
static void Main()
{
// Create two equal but distinct strings
string a = new string(new char[] {'h', 'e', 'l', 'l', 'o'});
string b = new string(new char[] {'h', 'e', 'l', 'l', 'o'});
Console.WriteLine (a==b);
Console.WriteLine (a.Equals(b));
// Now let's see what happens with the same tests but
// with variables of type object
object c = a;
object d = b;
Console.WriteLine (c==d);
Console.WriteLine (c.Equals(d));
}
}
結果是:
TrueTrueFalseTrue
第三行是 False,原因在於編譯器不知道 c 和 d 的內容都是字串引用,因而只能調用 == 的非重載版本。因為它們是對不同字串的引用,所以恒等運算子返回 False。
那麼,應該如何區別使用這些運算子呢?我的準則是:對於幾乎所有參考型別,當您希望測試相等性而不是引用一致性時,請使用 Equals。例外的情況是字串 - 使用 == 比較字串確實會使事情簡單得多,而且代碼可讀性更好,但是 您需要記住,該運算子的兩端都必須是類型字串運算式,才能使比較正常進行。
對於實值型別,我通常使用 ==,因為除非實值型別本身包含參考型別(這種情況極為罕見),否則是恒等還是相等的問題無關緊要。