【问题标题】:stable hashcode for IStructuralEquatable objectIStructuralEquatable 对象的稳定哈希码
【发布时间】:2014-04-24 08:38:23
【问题描述】:

我需要为对象构建一个稳定的(= 不随时间变化)哈希码。 具体来说,我不知道对象的确切类型。我做的唯一假设是它继承自 IStructuralEquatable。

所以我需要一个方法:

static string GetStableHashcode <T> (T object) where T: IStructuralEquatable

.Net 框架提供这种功能? 否则,使用哪种算法?

【问题讨论】:

  • 你的问题让我有些困惑。通常哈希码不会随时间变化,它们是整数,而不是字符串。您的泛型方法有一个类型参数T,但该类型不是函数签名的一部分,那么T 应该如何在函数中使用?无论如何,您可以使用 .NET 元组或匿名类型通过组合值来创建哈希码,但我不确定这是否能回答您的问题。
  • 是的,该函数可以返回一个整数(所以如果我需要一个字符串,我只需要序列化它)。 Object.GetHashCode(在 Tuple 或任何其他 .Net 类上)不稳定。 2 个执行实例(所以 2 个 AppDomain)将为同一个对象生成 2 个不同的哈希码!?!

标签: .net hashcode structural-equality


【解决方案1】:

您的每个对象都应使用基于对象内容的哈希码。如果您有一个包含 3 个整数的值类型,请在计算哈希码时使用它们。

这样,所有具有相同内容的对象都将具有相同的哈希码,与应用域和其他情况无关。

可以在this answer 中找到一个好的哈希码示例。

【讨论】:

  • 这不是通用解决方案。对象不是我的对象。这些只是实现IStructuralEquatable的对象
  • 但是结构相等的契约要求所有具有相同内容值的对象都是相等的。如果这些对象不包含满足该约定的相等/哈希码方法,则您必须自己包装它们并在包装器中为这些方法提供正确的实现。
【解决方案2】:

您的函数中不需要使用泛型,所以您的问题是如何实现该方法

static string GetStableHashcode(IStructuralEquatable obj) { ... }

唯一明智的解决方案是像这样实现它:

static string GetStableHashcode(IStructuralEquatable obj) {
  return obj.GetHashCode().ToString();
}

您担心Object.GetHashCode() 不提供稳定的值,并且该问题非常有效,如文档中以Caution 为标题的第一个框中所示:

  • 不要序列化哈希码值或将它们存储在数据库中。

  • [...]

  • 不要跨应用程序域或进程发送哈希码。在某些情况下,可以基于每个进程或每个应用程序域计算哈希码。

实际上,Object.GetHashCode 创建的一些哈希码是稳定的,如Int32.GetHashCodeString.GetHashCodeTuple.GetHashCode 使用的算法也会以“稳定的方式”组合哈希码。但是,这是一个实现细节,除非您想在代码中依赖它,否则您无法创建稳定的哈希码,并提供实现 IStructuralEquatable 的对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-24
    • 2013-06-18
    • 1970-01-01
    • 2014-01-06
    • 2014-05-30
    • 1970-01-01
    相关资源
    最近更新 更多