C#:Equals, ReferenceEquals与==的区别

来源:互联网 发布:淘宝上开网店要收费吗 编辑:程序博客网 时间:2024/05/01 18:45

==运算符:对于值类型,如果操作数的值相等,则==返回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()); // False32             Console.WriteLine(ReferenceEquals(c1, c3).ToString()); // False33             Console.WriteLine(ReferenceEquals(c1, c4).ToString()); // False34             Console.WriteLine(ReferenceEquals(c1, c5).ToString()); // True35             Console.WriteLine(ReferenceEquals(c1, c6).ToString()); // True36             Console.WriteLine();37             Console.WriteLine(Equals(c1, c2).ToString()); // False38             Console.WriteLine(Equals(c1, c3).ToString()); // False39             Console.WriteLine(Equals(c1, c4).ToString()); // False40             Console.WriteLine(Equals(c1, c5).ToString()); // True41             Console.WriteLine(Equals(c1, c6).ToString()); // True42             Console.WriteLine();43             Console.WriteLine(c1.Equals(c2).ToString()); // False44             Console.WriteLine(c1.Equals(c3).ToString()); // False45             Console.WriteLine(c1.Equals(c4).ToString()); // False46             Console.WriteLine(c1.Equals(c5).ToString()); // True47             Console.WriteLine(c1.Equals(c6).ToString()); // True48             Console.WriteLine();49             Console.WriteLine(c1 == c2); // False50             Console.WriteLine(c1 == c3); // False51             Console.WriteLine(c1 == c4); // False52             Console.WriteLine(c1 == c5); // True53             Console.WriteLine(c1 == c6); // True54             Console.WriteLine();55             Console.ReadLine();56         }57     }58 59     public class ReferneceClass60     {61         public int X62         {63             get;64             set;65         }66 67         public string Y68         {69             get;70             set;71         }72 73         public struct ValueStruce74         {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()); // False32             Console.WriteLine(ReferenceEquals(c1, c3).ToString()); // False33             Console.WriteLine(ReferenceEquals(c1, c4).ToString()); // False34             Console.WriteLine(ReferenceEquals(c1, c5).ToString()); // False35             Console.WriteLine(ReferenceEquals(c1, c6).ToString()); // False36             Console.WriteLine();37             Console.WriteLine(Equals(c1, c2).ToString()); // True38             Console.WriteLine(Equals(c1, c3).ToString()); // False39             Console.WriteLine(Equals(c1, c4).ToString()); // False40             Console.WriteLine(Equals(c1, c5).ToString()); // False41             Console.WriteLine(Equals(c1, c6).ToString()); // True42             Console.WriteLine();43             Console.WriteLine(c1.Equals(c2).ToString()); // True44             Console.WriteLine(c1.Equals(c3).ToString()); // False45             Console.WriteLine(c1.Equals(c4).ToString()); // False46             Console.WriteLine(c1.Equals(c5).ToString()); // False47             Console.WriteLine(c1.Equals(c6).ToString()); // True48             49             Console.ReadLine();50         }51     }52 53     public class ReferneceClass54     {55         public int X56         {57             get;58             set;59         }60 61         public string Y62         {63             get;64             set;65         }66     }67 68     public struct ValueStruce69     {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 Person35     {36         private string name;37 38         public string Name39         {40             get41             {42                 return name;43             }44             set45             {46                 name = value;47             }48         }49 50         public Person(string name)51         {52             this.name = name;53         }54     }55 }

运行结果:

 

 

 


<script type="text/javascript"><!--google_ad_client = "ca-pub-1944176156128447";/* cnblogs 首页横幅 */google_ad_slot = "5419468456";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
原创粉丝点击