C#中有兩種不同的相等:引用相等和值相等。值相等,即兩個對象包含相同的值。例如,兩個值為2的整數數具有值相等性。引用相等意味著要比較的兩個對象不是兩個對象,而是兩個“對象引用”,這兩個“對象引用”引用的是同一個對象。
1、對於實值型別
對於實值型別,如果對象的值相等,則相等運算子 (==) 返回 true,否則返回 false。
2、對於參考型別
對於string 以外的參考型別,如果兩個對象引用同一個對象,則 == 返回 true。對於 string 類型,== 比較字串的值。
==操作比較的是兩個變數的值是否相等。
equals()方法比較的是兩個對象的內容是否一致.equals也就是比較參考型別是否是對同一個對象的引用。
首先我們看一段程式:
代碼
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace CSharpDemo
7 {
8 class Person
9 {
10 private string name;
11
12 public string Name
13 {
14 get { return name; }
15 set { name = value; }
16 }
17
18 public Person(string name)
19 {
20 this.name = name;
21 }
22 }
23 class Program
24 {
25 static void Main(string[] args)
26 {
27 int i = 1;
28 int j = 1;
29 Console.WriteLine(i == j); //True
30 Console.WriteLine(i.Equals(j)); //True
31
32 string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
33 string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
34 Console.WriteLine(a == b); //True
35 Console.WriteLine(a.Equals(b)); //True
36
37 object g = a;
38 object h = b;
39 Console.WriteLine(g == h); //False
40 Console.WriteLine(g.Equals(h)); //True
41
42 Person p1 = new Person("person");
43 Person p2 = new Person("person");
44 Console.WriteLine(p1 == p2); //False
45 Console.WriteLine(p1.Equals(p2)); //False
46
47
48 Person p3 = new Person("person");
49 Person p4 = p3;
50 Console.WriteLine(p3 == p4); //True
51 Console.WriteLine(p3.Equals(p4)); //True
52
53 Console.ReadKey();
54
55 }
56 }
57 }
輸出結果在對應的行後面標出。
為什麼會出現這個答案呢?因為實值型別是儲存在記憶體中的堆棧(以後簡稱棧),而參考型別的變數在棧中僅僅是儲存參考型別變數的地址,而其本身則儲存在堆中。
==操作比較的是兩個變數的值是否相等,對於引用型變數表示的是兩個變數在堆中儲存的地址是否相同,即棧中的內容是否相同。
equals動作表示的兩個變數是否是對同一個對象的引用,即堆中的內容是否相同。
而字串是一個特殊的引用型類型,在C#語言中,重載了string 對象的很多方法方法(包括equals()方法),使string對象用起來就像是實值型別一樣。
因此在上面的例子中,字串a和字串b的兩個比較是相等的。
對於object g 和object h 時記憶體中兩個不同的對象,所以在棧中的內容是不相同的,故不相等。而g.equals(h)用的是string的equals()方法故相等(多態)。如果將字串a和b作這樣的修改:
string a="aa";
string b="aa";
則,g和h的兩個比較都是相等的。這是因為系統並沒有給字串b分配記憶體,只是將"aa"指向了b。所以a和b指向的是同一個字串(字串在這種賦值的情況下做了記憶體的最佳化)。
對於p1和p2,也是記憶體中兩個不同的對象,所以在記憶體中的地址肯定不相同,故p1==p2會返回false,又因為p1和p2又是對不同對象的引用,所以p1.equals(p2)將返回false。
對於p3和p4,p4=p3,p3將對對象的引用賦給了p4,p3和p4是對同一個對象的引用,所以兩個比較都返回true。