24

考虑到身份属性可能为空,以下哪一项是正确/更好的。

public override int GetHashCode()
{
    if (ID == null) {
        return base.GetHashCode();
    }
    return ID.GetHashCode();
}

或者

public override int GetHashCode()
{
    if (ID != null) {
        return ID.GetHashCode();
    }
     return 0;
}

更新 1:更新了第二个选项。

更新 2:以下是 Equals 实现:

public bool Equals(IContract other)
{
    if (other == null)
        return false;
    if (this.ID.Equals(other.ID)) {
        return true;
    }
    return false;
}

public override bool Equals(object obj)
{
    if (obj == null)
        return base.Equals(obj);
    if (!obj is IContract) {
        throw new InvalidCastException("The 'obj' argument is not an IContract object.");
    } else {
        return Equals((IContract)obj);
    }
}

ID是string类型。

4

3 回答 3

25

这实际上取决于您想要相等的含义 - 重要的是两个相等的对象返回相同的哈希码。ID 为空时相等是什么意思?目前,如果 ID 属性具有相同的值,您的 Equals 方法将必须返回 true ......但我们不知道如果 ID 为空,它会做什么。

如果你真的想要第一个版本的行为,我个人会使用:

return ID == null ? base.GetHashCode() : ID.GetHashCode();

编辑:根据您的 Equals 方法,您可以使用 GetHashCode 方法:

return ID == null ? 0 : ID.GetHashCode();

请注意,您的Equals(IContract other)方法也可能如下所示:

return other != null && object.Equals(this.ID, other.ID);

this.ID如果为空,您当前的实现实际上会抛出异常......

此外,您的Equals(object)方法不正确-如果传递了不适当的对象类型,则不应抛出异常,如果为null ,则应返回false...同上。obj所以你实际上可以使用:

public override bool Equals(object obj)
{
    return Equals(obj as IContract);
}

但是,我担心基于接口的平等。通常,即使实现了相同的接口,两个不同类型的类也不应该被认为是相等的。

于 2011-02-22T12:36:17.017 回答
5

您可以简单地return 0;,您需要为相同的值返回相同的 HashCode,并且 ID.GetHashCode() 通常不会返回 0,因此这样的 Hash 函数可以满足任何需求。由于您没有组合任何值(如 ID 和 Name Hashes ),其非常清晰的 ID 是 HashCode 的定义源,因此将 Null ID 固定为 0 听起来很合理。

否则,您对 GetHashCode 覆盖的整个方法仅考虑 ID 字段可能是错误的(并且您需要组合几个字段来计算它们的哈希值)

在您进行编辑后,我可以说第二个 Equals 覆盖的代码太多,只需将其替换为

public override bool Equals(object obj)
{
    return Equals(obj as Contract);
}

您的 Equals(IContract contract) 覆盖对我来说似乎有问题,因为只有定义合同的东西是 ID,如果 IContract 的字段多于 ID,它将是一个糟糕的 Equals 覆盖。

PS:实际上,如果 IContract 是一个接口,您可能需要将您的接口替换IEquatable<IContract>为一个具体的IEquatable<ClassName>合约,因为它的设计很糟糕,以便能够返回实现相同接口的不同类实例是相等的,因为定义上的相等性需要检查对象是否具有相等检查第一阶段的相同类型(通常在 99.9% 的情况下)

于 2011-02-22T12:40:58.557 回答
0

也许你想要的是这样的东西?

override int GetHashCode()
{
    if (ID != null)
        return ID.GetHashCode();

    return DBNull.Value.GetHashCode();
}

重要的是,两个具有空 ID 的对象是否应该被视为相等?

于 2011-02-22T12:39:37.660 回答