对象平等

时间:2014-06-03 12:26:51

标签: c# clr

Object base class具有以下代码,用于比较两个对象的相等性

public static bool Equals(Object objA, Object objB) 
    {
        if (objA==objB) {
            return true;
        } 
        if (objA==null || objB==null) {
            return false; 
        } 
        return objA.Equals(objB);
    } 

比较objA==objBobjA.Equals(objB)之间的区别是什么?为什么我们需要单独检查objA==objB

更新:源代码中的注释表示“Equality is defined as object equality for reference types and bitwise equality for value types”。因此,如果我们处理引用类型和objA!=objB那么我们必须返回false而不进行其他比较,不是吗? objA.Equals(objB)在这里看起来多余。

4 个答案:

答案 0 :(得分:3)

objA==objB检查引用相等性,其中objA.Equals(objB)可以被覆盖。因此,当引用相等时,显然我们不需要调用可能执行值相等的Equals方法。

没有必要比较参考相等性,我会说它是优化,因为可以覆盖值相等并且它们可能是昂贵的实现它们(BCL团队)当他们知道两者都是相同的参考时想要优化。

所以这只是因为如果引用相等,那么它们的值也相等。

答案 1 :(得分:3)

第一个比较是一个简单的引用标识比较 - 换句话说,objAobjB的值是指同一个对象(或者都是null)。这在Equals(object, object)中有两个目的:

  • 这是一种优化,因此当我们将对象与自身进行比较时,我们不需要实际调用Equals
  • 这使Equals(null, null)返回true而无需为其设置特殊情况

objA.Equals(objB)调用虚拟object.Equals(object)方法,该方法可以在子类中重写。 (Equals实现通常以与我们已经执行的相同的参考比较开始,再次出于优化目的......两次进行相同的比较是有点遗憾,但是避免使用它是有意义的。我们不需要时进行虚拟通话。)

例如,string会覆盖Equals,以便两个独立的string对象仍然可以相互相等。 (string重载 ==运算符与Equals具有相同的含义,但这与Equals(object, object)代码无关,因为重载是一个编译时问题...... ==中的Equals(object, object)只会永远执行参考比较。)

编辑:关于“Equality被定义为引用类型的对象相等性和值类型的按位相等性”的注释是Equals默认实现(这是注释发生的地方)。它与==无关,可以通过进一步覆盖Equals来覆盖该行为。

答案 2 :(得分:1)

==检查引用相等性。所有类型都可以覆盖Equals方法,因此调用objA.Equals(objB)的目的是根据自定义实现比较对象(如果有)。

答案 3 :(得分:1)

实例Equals()方法是虚方法,可以在派生类中重写。