1

我正在使用以下代码来测试 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 是一个超类,我应该如何处理它?它应该总是返回假,还是有时它应该是真的?

我该如何进行比较?

4

3 回答 3

3

这实际上取决于您想要平等的含义。

我不认为我曾经允许不同班级之间的平等。不过,您可能有一个案例。

还要记住,您可以使用自定义IEqualityComparer<T>. 每当您想以一种不是真正通用的方式测试相等性时,这是一个很好的策略,因为这意味着其他情况下的其他代码不会被您的覆盖所困扰。每种类型只能覆盖 Equals 一次,但您可以拥有任意数量的比较器。

于 2012-10-21T14:18:07.540 回答
1

只需摆脱 GetType() 比较并将 obj as 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。与所有其他实例方法一样,如果它们确实是类型的一部分,而不仅仅是辅助方法,则应仅将它们包含在类层次结构中

于 2012-10-21T14:19:01.837 回答
0

虽然在某些情况下,让不同类型的对象报告自己彼此相等可能很有用,但我强烈建议不要这样使用;我唯一能认为这是合理的情况是,如果所有类型都继承自一个公共基类,其中包括一个Equals使用各种虚拟方法的密封方法,询问对象它们支持哪些加速相等比较的方法,使用最好的可用方法方法,如果没有可用的加速方法,则将对象转换为规范形式并进行比较。

例如,考虑ImmutableFloatingPointMatrix实现双参数索引属性 getter 的抽象类型。如果两个矩阵具有相同的大小并且在相同的位置具有相同的值,则它们应该被认为是相等的。虽然派生类可以使用二维数组来保存矩阵的内容,但也可以使用许多其他存储方法。例如,可能有一个具体的IdentityMatrix类,它有一个Size字段,总是将它的维度报告为Sizex Size,并且有一个索引属性,它对主对角线上的单元格返回 1.0,在其他地方返回 0.0。也可以有一个DiagonalMatrix使用单个的Size-item 数组来保存对角线上的东西。虽然可以通过检查所有相应的元素来比较任何两个矩阵的相等性,但是DiagonalMatrix通过IdentitymMatrix确保两个矩阵的大小相同并且数组中的所有项都等于 1.0(不打扰检查主对角线之外的任何点,因为不会有任何点)。

即使使用Equals可以合理定义语义的类型,以便不同类型的对象报告自己是平等的,这也可能不是最好的主意。在可以使用自定义的情况下EqualityComparer,这可能比一个奇怪的覆盖更好Equals

于 2012-12-03T22:56:58.293 回答