繁体   English   中英

为什么Object类型的Equals的输入参数?

[英]Why is the input parameter of Equals of type Object?

我已经覆盖了Equals(对象输入)数千次,并且从没有更深地考虑过这个问题。 现在,经过几次喝酒,我开始思考它并且让我感到震惊,我不完全确定为什么会如此。

从语义上讲,平等操作检查两个东西是否是自身的副本。 通常,它是基于指针(参考值或任何人可能想要调用它)完成的。 有时,我们想将等式定义为例如,实例a的某些属性的总和与实例b的总和相同,而在某些实例上不一定相等。

但是,两个不同类型的对象不能有相同的参考,可以吗? 并且,即使两种类型具有相同的属性集(称为相同),键入相同,它仍然是苹果和橙子,因此比较将无意义(至少)或损坏逻辑。

在任何情况下(相等于所有意思), 等于操作的输入可能不同于被比较方, 并且仍然有意义吗?

你的假设是错误的:

从语义上讲,平等操作检查两个东西是否是自身的副本。 通常,它是基于指针(参考值或任何人可能想要调用它)完成的。

这是引用相等 ,它由Object.ReferenceEquals函数检查 (它是静态的,不可覆盖)

对象相等性不同,您可以应用所需的规则。 如果它不是那样的话,你会如何检查两个值类型 (在C#中不能保存相同的引用)?

考虑:

int a = 5;
int b = 5;
a.Equals(b); // what would this return? `a` and `b` are different objects

现在,对于问题的第二部分,根据您的需要,可能需要将对象视为不同类型的对象。 考虑:

public class Point2D {
  public int X, Y;
}

public class Point3D {
  public int X, Y, Z;

  public override bool Equals(object source) {
    var p2D = source as Point2D;
    if(p2D != null)
    {
      if(this.Z == 0 && p2D.X == this.X && p2D.Y == this.Y)
        return true;
      return false;
    }
    //...
  }
}

在这种情况下:

var p2D = new Point2D(5,5);  // <-- let's pretend we have the right constructor  
var p3D = new Point3D(5,5,0);
object.Equals(p3D,p2D); // <-- returns true
object.ReferenceEquals(p3D, p2D); // <-- returns false

对于性能(特别是对于值类型),您可能希望实现IEquatable<T>IEqualityComparer<T> (或者更好,从EqualityComparer<T>派生),这允许直接比较特定类型(无需将它打包到object之前),但这超出了这个答案的范围。

请注意,如果实现此接口,仍建议覆盖Object.Equals ,以便在两者之间匹配行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM