分享

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

 昵称10504424 2013-03-25

==运算符:对于值类型,如果操作数的值相等,则==返回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 }
复制代码

运行结果:

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多