A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 飞翔的33 中级黑马   /  2012-8-31 07:09  /  1913 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

       “==”操作比较的是两个变量的值是否相等,所以对于值类型,“==”就是比较两个变量的值,而对于引用类型,“==”就是比较两个变量对它们对象的引用是否相同,也就是引用类型的引用部分。
    equals()是object的一个虚方法,这个方法没被重写之前接受的是两个object类型的变量,也就是两个引用类型的变量,然后比较两个变量的实例部分,判断两个变量的实例是否相同,如果这个方法被子类重写了,那具体如何比较就是看子类自己的实现。而object本身还有个静态的equals()方法,这个方法先会直接比较两个变量所引用的是否是同一个对象(如果两个变量都是null的话,也算是相同的对象。),如果引用的不是同一个对象,就会再判断第一个对象和第二个对象是否为空,如果有一个为空,就直接返回false,如果两个都不为空,就会调用第一个参数的equals()方法,由于多态问题,还是会回到子类重写的equals()方法。如果要判断两个对象引用的是否是同一个变量的话,可以使用ReferenceEquals()方法,或者直接使用“==”,因为object类的ReferenceEquals()方法内部就是返回两个参数通过“==”比较的结果。
下面来看一段代码:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;

  5. namespace ConsoleApplication1
  6. {
  7.     class Person
  8.     {
  9.         private string name;

  10.         public string Name
  11.         {
  12.             get { return name; }
  13.             set { name = value; }
  14.         }

  15.         public Person(string name)
  16.         {
  17.             this.name = name;
  18.         }
  19.     }
  20. }
  21. using System;
  22. using System.Collections.Generic;
  23. using System.Linq;
  24. using System.Text;

  25. namespace ConsoleApplication1
  26. {
  27.     class Program
  28.     {
  29.         static void Main(string[] args)
  30.         {
  31.             string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
  32.             string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
  33.             Console.WriteLine(a == b);
  34.             Console.WriteLine(a.Equals(b));

  35.             object g = a;
  36.             object h = b;
  37.             Console.WriteLine(g == h);
  38.             Console.WriteLine(g.Equals(h));

  39.             Person p1 = new Person("jia");
  40.             Person p2 = new Person("jia");
  41.             Console.WriteLine(p1 == p2);
  42.             Console.WriteLine(p1.Equals(p2));


  43.             Person p3 = new Person("jia");
  44.             Person p4 = p3;
  45.             Console.WriteLine(p3 == p4);
  46.             Console.WriteLine(p3.Equals(p4));

  47.             Console.ReadLine();
  48.         }
  49.     }
  50. }

  51. 运行程序,会输出什么呢?
  52. 答案是 true,true,false,true,false,false,true,true。
  53. 为什么会出现这个答案呢?因为值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。
  54.     ==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。
  55.     equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
  56.     而字符串是一个特殊的引用型类型,在C#语言中,重载了string 对象的很多方法方法(包括equals()方法),使string对象用起来就像是值类型一样。
  57.     因此在上面的例子中,字符串a和字符串b的两个比较是相等的。
  58.     对于object g 和object h 时内存中两个不同的对象,所以在栈中的内容是不相同的,故不相等。而g.equals(h)用的是sting的equals()方法故相等(多太)。如果将字符串a和b作这样的修改:
  59.         string a="aa";
  60.         string b="aa";
  61. 则,g和h的两个比较都是相等的。这是因为系统并没有给字符串b分配内存,只是将"aa"指向了b。所以a和b指向的是同一个字符串(字符串在这种赋值的情况下做了内存的优化)。
  62. 对于p1和p2,也是内存中两个不同的对象,所以在内存中的地址肯定不相同,故p1==p2会返回false,又因为p1和p2又是对不同对象的引用,所以p1.equals(p2)将返回false。
  63. 对于p3和p4,p4=p3,p3将对对象的引用赋给了p4,p3和p4是对同一个对象的引用,所以两个比较都返回true。
  64. 如果我们对person的equals方法重写:
  65. using System;
  66. using System.Collections.Generic;
  67. using System.Linq;
  68. using System.Text;

  69. namespace ConsoleApplication1
  70. {
  71.     class Person
  72.     {
  73.         private string name;

  74.         public string Name
  75.         {
  76.             get { return name; }
  77.             set { name = value; }
  78.         }

  79.         public Person(string name)
  80.         {
  81.             this.name = name;
  82.         }

  83.         public override bool Equals(object obj)
  84.         {
  85.             if (!(obj is Person))
  86.                 return false;
  87.             Person per = (Person)obj;
  88.             return this.Name == per.Name;
  89.         }
  90.     }
  91. }那么p1.equals(p2),就会返回true。
复制代码

评分

参与人数 1技术分 +1 收起 理由
郑文 + 1

查看全部评分

1 个回复

倒序浏览
{:soso__17262223001374949512_4:}值得学习ing!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马