C# GetHashCode question



在这种情况下,重写GetHashCode函数的最佳方法是什么如果中至少有一个字段匹配,则认为my对象是相等的。

在通用Equals方法的情况下,示例可能如下所示:

    public bool Equals(Whatever other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        // Considering that the values can't be 'null' here.
        return other.Id.Equals(Id) || Equals(other.Money, Money) ||
               Equals(other.Code, Code);
    }

尽管如此,我还是很困惑如何为这种情况制作一个好的GetHashCode实现。

这应该怎么做?

谢谢。

这是Equals的一个糟糕定义,因为它不是可传递的。

考虑
x = { Id = 1, Money = 0.1, Code = "X" }
y = { Id = 1, Money = 0.2, Code = "Y" }
z = { Id = 3, Money = 0.2, Code = "Z" }

x == yy == z之后是x != z

此外,我们可以确定GetHashCode的唯一合理实现是常数映射。

假设xy是不同的对象。设z为对象

z = { Id = x.Id, Money = y.Money, Code = "Z" }

然后x == zy == z,使x.GetHashCode() == z.GetHashCode()y.GetHashCode() == z.GetHashCode()建立x.GetHashCode() == y.GetHashCode()。由于xy是任意的,我们已经确定GetHashCode是常数。

因此,我们已经证明GetHashCode的唯一可能实现是
private readonly int constant = 17;
public override int GetHashCode() {
    return constant;
}

所有这些都清楚地表明,您需要重新考虑您正在尝试模型的概念,并提出Equals的不同定义。

我认为你不应该使用等号。人们对相等的含义有着非常明确的概念,如果id不同但代码或名称相同,我不会认为它们是"相等的"。也许你需要一个不同的方法,比如"IsCompatible"。

如果您希望能够对它们进行分组,您可以在这些对象的列表上使用扩展方法tollookup()来使用谓词,该谓词将是您的IsCompatible方法。然后将它们分组。

黄金法则是:如果对象比较相等,它们必须产生相同的哈希码。

因此,一个符合(但我们说,不希望)的实现将是

public override int GetHashCode()
{
    return 0;
}

坦率地说,如果Id, NameCode是相互独立的,那么我不知道你是否可以做得更好。把这种类型的对象放到哈希表中是很痛苦的。

最新更新