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。