==运算符:对于值类型,如果操作数的值相等,则==返回true,否则返回false。对于string以外的引用类型,如果两个对象引用同一个对象,则==返回true。对于string类型,==比较字符串的值。
using System; class MainClass { static void Main() { // Numeric equality: True Console.WriteLine((2 + 2) == 4);//return true,这里比较的是值相等 // Reference equality: different objects, // same boxed value: False. object s = 1; object t = 1; Console.WriteLine(s == t);//return false,这里比较的是引用相等 Console.WriteLine(s.Equals(t).ToString());//return true,这里比较的是值相等 // Define some strings: string a = "hello"; string b = String.Copy(a); //注意:这里的Copy方法将在堆中创建一个新对象, 并将a的值拷贝到b中,也就是说a,b的值虽然相同,但是引用却不相同,a和b是不同的对象 string c = "hello"; //注意:这的操作设计到string的一个优化策略,对于string类型的两个变量a和c,如果系统发现a和c的内容相同,则直接将a的引用赋给c; //也就是说a和c的引用指向的是同一对象。(相同的引用肯定有相同的值,但是相同值却不一定有相同的引用) // Compare string values of a constant and an instance: True Console.WriteLine(a == b);//return true,string比较特殊,string的很多方法被重写过, 这里比较的是值相等,即内容相等 Console.WriteLine(a.Equals(b).ToString()); //return true,这里比较的是值相等,Equals()方法是string上的方法 // Compare string references; // a is a constant but b is an instance: False. Console.WriteLine((object)a == (object)b);/*return false,这里比较的是引用相等,因为string的==操作被重写过,所以强转为object类型后再比较其引用。 因为b创建新的对象, 所以虽然a和b的值相同,但终究是不同的引用*/ Console.WriteLine((object)a.Equals((object)b).ToString()); //return true,这里比较的是值相等, Equals()方法是string上的方法 // Compare string references, both constants // have the same value, so string interning // points to same reference: True. Console.WriteLine((object)a == (object)c);//return true,这里的a和c的值相同,那么编译器认为a和c指向同一个引用 Console.WriteLine((object)a.Equals((object)c).ToString()); //return true,这里比较的是值相等,Equals()方法是string上的方法 } }
引用类型的比较:
1 using System; 2 3 namespace ConsoleApplication14 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 ReferneceClass c1 = new ReferneceClass(); 10 c1.X = 1; 11 c1.Y = "OK"; 12 13 ReferneceClass c2 = new ReferneceClass(); 14 c2.X = 1; 15 c2.Y = "OK"; 16 17 ReferneceClass c3 = new ReferneceClass(); 18 c3.X = 1; 19 c3.Y = "OK!"; 20 21 ReferneceClass c4 = new ReferneceClass(); 22 c4.X = 2; 23 c4.Y = "OK"; 24 25 ReferneceClass c5 = new ReferneceClass(); 26 c5 = c1; 27 c5.X = 2; 28 29 ReferneceClass c6 = c1; 30 31 Console.WriteLine(ReferenceEquals(c1, c2).ToString()); // False 32 Console.WriteLine(ReferenceEquals(c1, c3).ToString()); // False 33 Console.WriteLine(ReferenceEquals(c1, c4).ToString()); // False 34 Console.WriteLine(ReferenceEquals(c1, c5).ToString()); // True 35 Console.WriteLine(ReferenceEquals(c1, c6).ToString()); // True 36 Console.WriteLine(); 37 Console.WriteLine(Equals(c1, c2).ToString()); // False 38 Console.WriteLine(Equals(c1, c3).ToString()); // False 39 Console.WriteLine(Equals(c1, c4).ToString()); // False 40 Console.WriteLine(Equals(c1, c5).ToString()); // True 41 Console.WriteLine(Equals(c1, c6).ToString()); // True 42 Console.WriteLine(); 43 Console.WriteLine(c1.Equals(c2).ToString()); // False 44 Console.WriteLine(c1.Equals(c3).ToString()); // False 45 Console.WriteLine(c1.Equals(c4).ToString()); // False 46 Console.WriteLine(c1.Equals(c5).ToString()); // True 47 Console.WriteLine(c1.Equals(c6).ToString()); // True 48 Console.WriteLine(); 49 Console.WriteLine(c1 == c2); // False 50 Console.WriteLine(c1 == c3); // False 51 Console.WriteLine(c1 == c4); // False 52 Console.WriteLine(c1 == c5); // True 53 Console.WriteLine(c1 == c6); // True 54 Console.WriteLine(); 55 Console.ReadLine(); 56 } 57 } 58 59 public class ReferneceClass 60 { 61 public int X 62 { 63 get; 64 set; 65 } 66 67 public string Y 68 { 69 get; 70 set; 71 } 72 73 public struct ValueStruce 74 { 75 public int x; 76 public string y; 77 } 78 } 79 }
c1,c2,c3,c4为不同的实例,c1,c5,c6是同一个引用
1 using System; 2 3 namespace ConsoleApplication14 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 ValueStruce c1 = new ValueStruce(); 10 c1.x = 1; 11 c1.y = "OK"; 12 13 ValueStruce c2 = new ValueStruce(); 14 c2.x = 1; 15 c2.y = "OK"; 16 17 ValueStruce c3 = new ValueStruce(); 18 c3.x = 1; 19 c3.y = "OK!"; 20 21 ValueStruce c4 = new ValueStruce(); 22 c4.x = 2; 23 c4.y = "OK"; 24 25 ValueStruce c5 = new ValueStruce(); 26 c5 = c1; 27 c5.x = 2; 28 29 ValueStruce c6 = c1; 30 31 Console.WriteLine(ReferenceEquals(c1, c2).ToString()); // False 32 Console.WriteLine(ReferenceEquals(c1, c3).ToString()); // False 33 Console.WriteLine(ReferenceEquals(c1, c4).ToString()); // False 34 Console.WriteLine(ReferenceEquals(c1, c5).ToString()); // False 35 Console.WriteLine(ReferenceEquals(c1, c6).ToString()); // False 36 Console.WriteLine(); 37 Console.WriteLine(Equals(c1, c2).ToString()); // True 38 Console.WriteLine(Equals(c1, c3).ToString()); // False 39 Console.WriteLine(Equals(c1, c4).ToString()); // False 40 Console.WriteLine(Equals(c1, c5).ToString()); // False 41 Console.WriteLine(Equals(c1, c6).ToString()); // True 42 Console.WriteLine(); 43 Console.WriteLine(c1.Equals(c2).ToString()); // True 44 Console.WriteLine(c1.Equals(c3).ToString()); // False 45 Console.WriteLine(c1.Equals(c4).ToString()); // False 46 Console.WriteLine(c1.Equals(c5).ToString()); // False 47 Console.WriteLine(c1.Equals(c6).ToString()); // True 48 49 Console.ReadLine(); 50 } 51 } 52 53 public class ReferneceClass 54 { 55 public int X 56 { 57 get; 58 set; 59 } 60 61 public string Y 62 { 63 get; 64 set; 65 } 66 } 67 68 public struct ValueStruce 69 { 70 public int x; 71 public string y; 72 } 73 }
- 静态ReferenceEquals,从方法名也可以看出比较的是引用地址,在堆值类型进行比较的时候,始终为false,即使是ReferenceEquals(1,1),因为这里它这里把值先装箱再进行比较,所以两个引用地址是不一样的,但是ReferenceEquals(null,null)的值是True。
- 静态方法Equals(object objA, object objB) 这个方法其实最终调用了虚拟Equals方法的不同重载。
- 虚拟Equals方法,可在不同类中重载,比如String.Equals方法就是用于判断两个字符串的内容是否相等。一般来说,对于值类型,类型相同,并且数值相同(对于Struct的每个成员都必须相同),则Equals返回True,否则返回False。而对于引用类型,默认的行为与ReferenceEquals的行为相同,仅有两个对象指向同一个Reference的时候才返回True。静态Equals相比虚拟Equals方法有一个优点,就在于它不用考虑比较的对象是否为null。
- ==运算符,对于内置的值类型,直接判断两个对象的值是否相等,并会根据需要对对象进行类型转换,对于用户定义的值类型,比如Struct,不可使用;对于引用类型,默认的行为与ReferenceEquals的行为相同,但是很多类对==进行了重载,比如String。
1 using System; 2 3 namespace ConsoleApplication12 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' }); 10 string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' }); 11 Console.WriteLine(a == b); 12 Console.WriteLine(a.Equals(b)); 13 14 object g = a; 15 object h = b; 16 Console.WriteLine(g == h); 17 Console.WriteLine(g.Equals(h)); 18 19 Person p1 = new Person("jia"); 20 Person p2 = new Person("jia"); 21 Console.WriteLine(p1 == p2); 22 Console.WriteLine(p1.Equals(p2)); 23 24 Person p3 = new Person("jia"); 25 Person p4 = p3; 26 Console.WriteLine(p3 == p4); 27 Console.WriteLine(p3.Equals(p4)); 28 29 Console.ReadLine(); 30 31 } 32 } 33 34 class Person 35 { 36 private string name; 37 38 public string Name 39 { 40 get 41 { 42 return name; 43 } 44 set 45 { 46 name = value; 47 } 48 } 49 50 public Person(string name) 51 { 52 this.name = name; 53 } 54 } 55 }
运行结果: