CLR中將“相等性”分為兩類: 1、值相等性:兩個變量包含的數值相等。 2、引用相等性:兩個變量引用的是內存中的同一個對象。 但並不是所有的類型的比較都是按照其本身,比如string是一個特殊的引用類型,但是在FCL中,string的比較就被重載為針對“類型的值”的比較,而不是“引用本身”的比較。對於自定義類型來說,如果想要實現這樣的值比較而不是引用比較的話,則需要重載Equals方法,比如對於Person類,如果IDCode相同,我們可以認為他們是同一個人。 復制代碼 class Person { public string IDCode { get; private set; } public Person(string idCode) { this.IDCode = idCode; } public override bool Equals(object obj) { return IDCode == (obj as Person).IDCode; } } 復制代碼 此時通過Equals去比較的話,則就會通過重載後的方法來進行了。 object a = new Person("ABC"); object b = new Person("ABC"); Console.WriteLine(a == b); //False Console.WriteLine(a.Equals(b)); //True 說到這裡,作者依然沒說白“==”和“Equals”的區別,只是說了一句建議的話:“對於引用類型,我們要定義值相等性,應該僅僅去重載Equals方法,同時讓==表示引用相等性”。 同時,為了明確有一種方法來肯定比較的是“引用相等性”,FCL提供了Object.ReferenceEquals方法。 bool equal= object.ReferenceEquals(object a,object b); 外事不決問Google,內事不決靠反編譯、MSDN了。為了弄懂==和Equals的區別,我作如下搜集整理: 1、==是運算符,而Equals是方法; 2、對於值類型、string類型,==和Equals都是比較值內容相等,使用ILSpy對Int類型進行反編譯觀察;int類型中的Equals方法內部邏輯就是“==”; // int [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] public bool Equals(int obj) { return this == obj; } string類型則是判斷引用地址是否相同或者值內容是否相同,兩者有一個符合條件則視為“相等”,請看string類的反編譯代碼。 復制代碼 // string [__DynamicallyInvokable, ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] public bool Equals(string value) { if (this == null) { throw new NullReferenceException(); } return value != null && (object.ReferenceEquals(this, value) || (this.Length == value.Length && string.EqualsHelper(this, value))); } 復制代碼 3、對於引用類型,==和Equals都是比較棧內存中的地址是否相等,並且自定義類型中可以進行運算符重載== 或者Override Equals 來改寫認為兩對象相等的條件,比如Person類中,我認為只要IDCard相同即對象相同等,此時可以進行重寫或者重載。