我使用以下代码测试Equals
public override bool Equals(object obj)
{
// Equals must return false on compares to null.
if (obj == null || GetType() != obj.GetType())
return false;
Foo fooItem = obj as Foo;
return fooItem.FooId == this.FooId;
}
如果obj是超类,我应该如何处理?它应该总是返回错误,还是有时候它应该是真的?
如何进行比较?
答案 0 :(得分:3)
这实际上取决于你想要平等的意思。
我认为我从未允许不同类之间的平等。不过,你可能有一个案例。
另请注意,您可以使用自定义IEqualityComparer<T>
。每当你想以一种不是真正通用的方式测试相等性时,这是一个很好的策略,因为这意味着其他情况下的其他代码不会被你的覆盖所困扰。每种类型只能覆盖一次Equals,但您可以拥有任意数量的比较器。
答案 1 :(得分:1)
简单地删除GetType()比较并将obj作为Foo移动到第一行。
然后代码
public override bool Equals(object obj)
{
var fooItem = obj as Foo;
// Equals must return false on compares to null.
if (obj == null) {
return false;
}
return fooItem.FooId == this.FooId;
}
这假设所有Foo甚至派生一次或者实现上述Equals
覆盖的类被密封,就意味着完全值比较。
如果所有Foos没有有意义的值比较(包括派生一次),那么我建议使用IEqualityComaprer。与所有其他实例方法一样,如果它们确实是类型的一部分而不仅仅是辅助方法,那么您应该只将它们包含在您的类层次结构中
答案 2 :(得分:0)
虽然在某些情况下,让不同类型的对象报告自己彼此相等可能会有用,但我强烈建议不要使用此类用法;唯一一次我可以看到它可能是合理的,如果从包含使用各种虚方法的密封Equals
方法的公共基类继承的所有类型都要求对象支持加速相等比较的方法,使用最佳可用方法,如果没有加速方法,则将对象转换为规范形式并进行比较。
例如,考虑实现两参数索引属性getter的抽象ImmutableFloatingPointMatrix
类型。如果两个矩阵具有相同的大小,并且在相同的位置具有相同的值,则应该认为它们是相等的。虽然派生类可能使用二维数组来保存矩阵的内容,但许多其他存储方法也是可能的。例如,可能有一个具有单个IdentityMatrix
字段的具体Size
类,始终将其维度报告为Size
x Size
,并且具有返回1.0的索引属性对于主对角线上的细胞和其他地方的0.0。也可以有一个DiagonalMatrix
使用单个Size
- 项数组来保持对角线上的东西。虽然可以通过检查所有相应的元素来比较任何两个矩阵的相等性,但是例如检查通过确保两个矩阵的大小相同,并且阵列中的所有项目都等于1.0(不打扰检查主对角线外的任何点,因为对DiagonalMatrix
IdentitymMatrix
可以更好地处理Equals
不会有任何)。
即使使用一种类型,其中EqualityComparer
的语义可以明智地定义,以便不同类型的对象将自己报告为相等,但它可能不是最好的主意。如果可以使用自定义Equals
,则可能比{{1}}的奇怪覆盖更好。