我已经数次覆盖了Equals(对象输入)并且从未考虑过这个问题.现在,经过几次喝酒后,我开始思考它,它让我感到震惊,我不完全确定为什么会如此.
从语义上讲,平等操作检查两个东西是否是自身的副本.通常,它是基于指针(参考值或任何人可能想要调用它)完成的.有时,我们希望将等式定义为例如实例a的某些属性的总和与实例b的相同,不一定在它们中的任何一个上相等.
但是,两个不同类型的对象不能有相同的参考,可以吗?并且,即使两种类型具有相同的属性集(称为相同),键入相同,它仍然是苹果和橙子,因此比较将无意义(至少)或损坏逻辑.
有没有(我的意思是任何一个)场合,Equals操作的输入可能是不同类型的,然后是同意并仍然有意义?
你的假设是错误的:
从语义上讲,平等操作检查两个东西是否是自身的副本.通常,它是基于指针(参考值或任何人可能想要调用它)完成的.
这是引用相等,它由Object.ReferenceEquals函数检查(它是静态的,不可覆盖)
对象相等性不同,您可以应用所需的规则.如果它不是那样的话,你会如何检查两个值类型(在C#中不能包含相同的引用)?
考虑:
int a = 5;
int b = 5;
a.Equals(b); // what would this return? `a` and `b` are different objects
Run Code Online (Sandbox Code Playgroud)
现在,对于问题的第二部分,根据您的需要,可能需要将对象视为不同类型的对象.考虑:
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;
}
//...
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下:
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
Run Code Online (Sandbox Code Playgroud)
对于性能(特别是对于值类型),您可能希望实现IEquatable<T>或IEqualityComparer<T>(或者更好,从中派生EqualityComparer<T>),这允许直接比较特定类型(无需将其打包到object之前),但这超出了范围这个答案.
请注意,Object.Equals如果您实现此接口,仍建议覆盖,以便在两者之间匹配行为.
| 归档时间: |
|
| 查看次数: |
105 次 |
| 最近记录: |