建议11: 区别对待==和Equals

转载 2016年08月30日 15:36:04

建议11: 区别对待==和Equals

在开始本建议之前,首先要明确概念“相等性”。CLR中将“相等性”分为两类:“值相等性”和“引用相等性”。如果用来比较的两个变量所包含的数值相等,那么将其定义为“值相等性”;如果比较的两个变量引用的是内存中的同一个对象,那么将其定义为“引用相等性”。

无论是操作符“==”还是方法“Equals”,都倾向于表达这样一个原则:

对于值类型,如果类型的值相等,就应该返回True。

对于引用类型,如果类型指向同一个对象,则返回True。

下面的代码输出所遵循的就是以上原则:

  1. static void ValueTypeOPEquals()  
  2. {  
  3.     int i = 1;  
  4.     int j = 1;  
  5.     //True  
  6.     Console.WriteLine(i == j);  
  7.     j = i;  
  8.     //True  
  9.     Console.WriteLine(i == j);  
  10. }  
  11.  
  12. static void ReferenceTypeOPEquals()  
  13. {  
  14.     object a = 1;  
  15.     object b = 1;  
  16.     //False  
  17.     Console.WriteLine(a == b);  
  18.     b = a;  
  19.     //True  
  20.     Console.WriteLine(a == b);  
  21. }  
  22.  
  23. static void ValueTypeEquals()  
  24. {  
  25.     int i = 1;  
  26.     int j = 1;  
  27.     //True  
  28.     Console.WriteLine(i.Equals(j));  
  29.     j = i;  
  30.     //True  
  31.     Console.WriteLine(i.Equals(j));  
  32. }  
  33.  
  34.  static void ReferenceTypeEquals()  
  35. {  
  36.     object a = new Person("NB123");  
  37.     object b = new Person("NB123");  
  38.     //False  
  39.     Console.WriteLine(a.Equals(b));  
  40.     b = a;  
  41.     //True  
  42.     Console.WriteLine(a.Equals(b));  

但是,我们同时也要了解,无论是操作符“==”还是“Equals”方法都是可以被重载的。比如,对于string这样一个特殊的引用类型,微软觉得它的现实意义更接近于值类型,所以,在FCL中,string的比较被重载为针对“类型的值”的比较,而不是针对“引用本身”的比较。

从设计上来说,很多自定义的类型(尤其是自定义的引用类型)会存在和string类型比较接近的情况。如例子中所举的类型Person,在现实生活中,如果两者的IDCode是相等的,我们就认为两者是同一个人,这个时候,就要重载Equals这个方法,代码如下所示:

  1. class Person  
  2. {  
  3.     public string IDCode { get; private set; }  
  4.  
  5.     public Person(string idCode)  
  6.     {  
  7.         this.IDCode = idCode;  
  8.     }  
  9.  
  10.     public override bool Equals(object obj)  
  11.     {  
  12.         return IDCode == (obj as Person).IDCode;  
  13.     }  

这时,再通过Equals去比较两个具有相同IDCode的Person对象的值,返回的就会是true,代码如下所示:

  1. object a = new Person("NB123");  
  2. object b = new Person("NB123");  
  3. //False  
  4. Console.WriteLine(a == b);  
  5. // True  
  6. Console.WriteLine(a.Equals(b)); 

这里,再引出操作符“==”和“Equals”方法之间的一点区别。一般来说,对于引用类型,我们要定义“值相等性”,应该仅仅去重载Equals方法,同时让“==”表示“引用相等性”。

注意 由于操作符“==”和“Equals”方法从语法实现上来说,都可以被重载为表示“值相等性”和“引用相等性”。所以,为了明确有一种方法肯定比较的是“引用相等性”,FCL中提供了Object. ReferenceEquals方法。该方法比较的是:两个示例是否是同一个示例。

转自:《编写高质量代码改善C#程序的157个建议》陆敏技

Tip11 区别对待==和Equals

Tip11 区别对待==和Equals “相等性”分为两类: 1、“值相等性”——比较的两个变量所包含的数值相等。 2、“引用相等性”——比较的两个变量引用的是内存中的同一个对象。“==”和“E...
  • q136780964
  • q136780964
  • 2017年08月02日 09:38
  • 81

建议94:区别对待override和new

建议94:区别对待override和new override和new使类型体系应为继承而呈现出多态性。多态要求子类具有与基类同名的方法,override和new的作用就是: 如果子类中的方法前面带...
  • houwc
  • houwc
  • 2016年09月08日 15:46
  • 209

建议3: 区别对待强制转型与as和is

建议3: 区别对待强制转型与as和is 在阐述本建议之前,首先需要明确什么是强制转型,以及强制转型意味着什么。从语法结构上来看,类似下面的代码就是强制转型。 secondType = (Secon...
  • houwc
  • houwc
  • 2016年08月29日 11:45
  • 507

建议3 区别对待强制转型与as和is

强转和as的区别 如果类型之间都上溯到了某个共同的基类,那么根据此基类进行的转型(即基类转型为子类本身)应该使用as。子类与子类之间的转型,则应该提供转换操作符,以便进行强制转型。 as操作符不能...
  • yijunwanghaha
  • yijunwanghaha
  • 2017年05月02日 22:40
  • 176

关于"".equals(str)和str.equals("")的区别

通过 String str = null; //if(str.equals("123")){} if("".equals(str)){}
  • liuzhidong123
  • liuzhidong123
  • 2014年09月14日 09:03
  • 6548

Java 中 Equals和==的区别

在谈论equals和==的区别前,我们先简单介绍一下JVM中内存分配的问题。 在JVM中 内存分为栈内存和堆内存。二者有什么区别呢? 当我们创建一个对象(new Object)时,就会调用它的构造函数...
  • tcytcy123
  • tcytcy123
  • 2016年03月09日 16:19
  • 17342

hibernate实体实现hashcode与equals方法

为什么Hibernate建议你的实体类实现hashCode和equals方法? 因为Hibernate使用了一级和二级缓存,很多查询为了提高效率Hibernate都会先从缓存中进行查找,然后再从...
  • wenzhihui_2010
  • wenzhihui_2010
  • 2013年09月02日 10:18
  • 1633

==和equals()比较

package com.liaojianya.chapter1; /** * This program demonstrates the difference between == and equa...
  • Andya_net
  • Andya_net
  • 2016年07月28日 09:24
  • 494

Java中==和equals的区别,equals和hashCode的区别

==是运算符,用于比较两个变量是否相等。 equals,是Objec类的方法,用于比较两个对象是否相等,默认Object类的equals方法是比较两个对象的地址,跟==的结果一样。Object的eq...
  • tiantiandjava
  • tiantiandjava
  • 2015年07月21日 17:01
  • 19815

java之"equals"和"=="的区别

java之String和Integer等包装类的"equals"和"=="的区别
  • xingzhemoluo
  • xingzhemoluo
  • 2014年10月17日 18:47
  • 1537
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:建议11: 区别对待==和Equals
举报原因:
原因补充:

(最多只允许输入30个字)