C# 中有兩種不同的相等:引用相等和值相等。
◎值相等是大家普遍理解的意義上的相等:它意味著兩個對象包含相同的值。
◎引用相等意味著要比較的不是兩個對象,而是兩個對象引用,且兩者引用的是同一個對象。
Equals:
下面的語句中,x、y 和 z 表示不為 null 的對象引用。
* 除涉及浮點型的情況外,x.Equals(x) 都返回 true。
* x.Equals(y) 返回與 y.Equals(x) 相同的值。
* 如果 x 和 y 都為 NaN,則 x.Equals(y) 返回 true。
* 若且唯若 x.Equals(z) 返回 true 時,(x.Equals(y) && y.Equals(z)) 才返回 true。
* 只要不修改 x 和 y 引用的對象,對 x.Equals(y) 的相繼調用將返回相同的值。
* x.Equals(null) 返回 false。
==:
對於預定義的實值型別,如果運算元的值相等,則相等運算子 (==) 返回 true,否則返回 false。
對於 string 以外的參考型別,如果兩個運算元引用同一個對象,則 == 返回 true。
對於 string 類型,== 比較字串的值。
Equals與==的區別
"==" : 操作比較的是兩個變數的值是否相等,對於引用型變數表示的是兩個變數在堆中儲存的地址是否相同,即棧中的內容是否相同。
"equals" : 動作表示的兩個變數是否是對同一個對象的引用,即堆中的內容是否相同。
而字串是一個特殊的引用型類型,在C#語言中,重載了string 對象的很多方法方法(包括equals()方法),使string對象用起來就像是實值型別一樣。
執行個體
C# 代碼
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Person { private string name; public string Name { get { return name; } set { name = value; } } public Person(string name) { this.name = name; } } class program { static void Main(string[] args) { 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)); object g = a; object h = b; Console.WriteLine(g == h); Console.WriteLine(g.Equals(h)); Person p1 = new Person("jia"); Person p2 = new Person("jia"); Console.WriteLine(p1 == p2); Console.WriteLine(p1.Equals(p2)); Person p3 = new Person("jia"); Person p4 = p3; Console.WriteLine(p3 == p4); Console.WriteLine(p3.Equals(p4)); Console.ReadLine(); } } }
輸出結果
true ,true ,false ,true ,false ,false ,true ,true 。
總結如下:
1、對於實值型別,==和equals等價,都是比較儲存資訊的內容。
2、對於參考型別,==比較的是參考型別在棧中的地址,equals方法則比較的是參考型別在託管堆中的儲存資訊的內容。
3、對於string類要特殊處理,它是一個內部已經處理好了equals方法和==的類,故==和equals等價,都是比較儲存資訊的內容。
4、對於一些自訂的類,我們有必要重載equals方法,否則它預設為基類的equals方法(基類沒有重載Equals方法則為Object類中的Equals方法),他們的比較也為地址,而不是參考型別在託管堆中的儲存資訊的內容。