【问题标题】:How to guarantee equal hash codes if all properties are "Equal"?如果所有属性都“相等”,如何保证相等的哈希码?
【发布时间】:2022-01-13 02:46:39
【问题描述】:

我当前的解决方案(A, B, C, D, ...).GetHashCode() 是否保证对于具有“相等”项的元组始终相同?

public class Pair
{
    public int X { get; set; }
    public int Y { get; set; }

    public Pair(int x, int y)
    {
        X = x;
        Y = y;
    }

    public override bool Equals(object other) => Equals(other as Pair);

    public virtual bool Equals(Pair other)
    {
        if (other is null)
        {
            return false;
        }
        if (object.ReferenceEquals(this, other))
        {
            return true;
        }
        if (this.GetType() != other.GetType())
        {
            return false;
        }
        return X == other.X && Y == other.Y;
    }

    public override int GetHashCode() => (X, Y).GetHashCode();

    public static bool operator ==(Pair lhs, Pair rhs)
    {
        if (lhs is null)
        {
            if (rhs is null)
            {
                return true;
            }
            return false;
        }
        return lhs.Equals(rhs);
    }

    public static bool operator !=(Pair lhs, Pair rhs) => !(lhs == rhs);
}

在此代码中始终保证打印1

var uniquePairs = new HashSet<Pair>();
uniquePairs.Add(new Pair(2, 4));
uniquePairs.Add(new Pair(2, 4));
uniquePairs.Add(new Pair(2, 4));
uniquePairs.Add(new Pair(2, 4));
Console.WriteLine(uniquePairs.Count);

如果有更多的非平凡类型属性呢?

有哪些可靠的GetHashCode 解决方案可用于此类类,如果所有(非必要的整数)成员都相同,则可以保证相同的哈希值?

【问题讨论】:

  • not 哈希码不是永久值
  • @LeiYang 是否在运行时之间保留哈希码无关
  • 我认为在您的用例中哈希码是可靠的(所有事情只发生在一个进程中)。实际上,这是许多复合对象获取哈希码的方式。
  • @LeiYang 我以前经常看到这种模式,但是this answer“结合每个对象的哈希码(和一个额外的随机种子)”让我想检查
  • 如果你指的是微软的实现,我认为他们避免使用GetHashCode 以获得更好的性能。

标签: c# .net-standard-2.0


【解决方案1】:

人们通常使用从字段值派生的一些算术来提供良好的伪随机分布,但如果所有字段都相等,则计算结果相同。看看这个:

General advice and guidelines on how to properly override object.GetHashCode()

此外,如果您想了解有关该主题的更多信息,请查看 Microsoft 文档。

如果您的目标只是让类的相等性由字段匹配而不是通过引用确定,C# 有一个新的record 引用类型,您可以使用它默认执行此操作。如果您使用的是最新版本的 C#/.NET,这将是可行的方法。

如果您遇到任何必须安全的非常复杂的问题,请考虑使用一些强大的哈希算法,例如 SHA-256 ... 将您的所有字段转换为填充缓冲区或字节,然后通过 SHA- 256(所有这些都可以在 System.Security.Cryptography 中找到)。您将获取 SHA-256 输出并选择其中的 4 个字节以生成 32 位整数。冲突的可能性非常非常小(当然,只有 32 位仍有可能)。

【讨论】:

    猜你喜欢
    • 2014-10-02
    • 1970-01-01
    • 2013-02-03
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    • 2012-09-24
    相关资源
    最近更新 更多