C# GetHashCode 问题

发布于 2024-10-30 20:16:22 字数 605 浏览 1 评论 0原文

对于这种情况,重写 GetHashCode 函数的最佳方法是什么? 如果其中至少有一个字段匹配,我的对象将被视为相等。

在通用 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 实现感到困惑。

这应该如何完成?

谢谢。

What would be the best way to override the GetHashCode function for the case, when
my objects are considered equal if there is at least ONE field match in them.

In the case of generic Equals method the example might look like this:

    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);
    }

Still, I'm confused about making a good GetHashCode implementation for this case.

How should this be done?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

偏闹i 2024-11-06 20:16:22

这是 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 == zx != z

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

假设 x 和 y 是不同的对象。设 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;
}

所有这些放在一起清楚地表明您需要重新思考您正在尝试模型的概念,并提出 的不同定义>等于

This is a terrible definition of Equals because it is not transitive.

Consider

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

Then x == y and y == z but x != z.

Additionally, we can establish that the only reasonable implementation of GetHashCode is a constant map.

Suppose that x and y are distinct objects. Let z be the object

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

Then x == z and y == z so that x.GetHashCode() == z.GetHashCode() and y.GetHashCode() == z.GetHashCode() establishing that x.GetHashCode() == y.GetHashCode(). Since x and y were arbitrary we have established that GetHashCode is constant.

Thus, we have shown that the only possible implementation of GetHashCode is

private readonly int constant = 17;
public override int GetHashCode() {
    return constant;
}

All of this put together makes it clear that you need to rethink the concept you are trying model, and come up with a different definition of Equals.

瀞厅☆埖开 2024-11-06 20:16:22

我认为你不应该为此使用 Equals。人们对等于的含义有一个非常明确的概念,如果 ID 不同但代码或名称相同,我不会认为它们是“等于”。也许您需要一种不同的方法,例如“IsCompatible”。

如果您希望能够对它们进行分组,您可以在这些对象的列表上使用扩展方法 ToLookup(),以使用 IsCompatible 方法作为谓词。然后他们就会被分组。

I don't think you should be using Equals for this. People have a very explicit notion of what equals means, and if the Ids are different but the code or name are the same, I would not consider those "Equal". Maybe you need a different method like "IsCompatible".

If you want to be able to group them, you could use the extension method ToLookup() on a list of these objects, to use a predicate which would be your IsCompatible method. Then they would be grouped.

两仪 2024-11-06 20:16:22

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

因此,坦率地说

public override int GetHashCode()
{
    return 0;
}

,如果 < code>Id、NameCode 彼此独立,那么我不知道你是否可以做得更好。将这种类型的对象放入哈希表将会很痛苦。

The golden rule is: if the objects compare equal, they must produce the same hash code.

Therefore a conforming (but let's say, undesirable) implementation would be

public override int GetHashCode()
{
    return 0;
}

Frankly, if Id, Name and Code are independent of each other then I don't know if you can do any better. Putting objects of this type in a hash table is going to be painful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文