GetHashCode方法会为不同AppDomain之间的对象返回不同的结果吗?

时间:2014-09-03 11:30:17

标签: c# hash

根据this Eric博客,

规则:GetHashCode的消费者不能依赖它随着时间的推移或跨appdomains的稳定性。 假设您有一个Customer对象,其中包含一系列字段,如Name,Address等。如果在两个不同的进程中使用完全相同的数据生成两个这样的对象,则它们不必返回相同的哈希代码。如果您在星期二的一个进程中创建这样的对象,将其关闭,并在星期三再次运行程序,则哈希码可以不同。 这在过去曾经被人咬伤过。 System.String.GetHashCode的文档特别指出,两个相同的字符串在CLR的不同版本中可以具有不同的哈希码,实际上它们也是如此。不要在数据库中存储字符串哈希并期望它们永远相同,因为它们不会。

我正在使用这个课程,

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string ModelNumber { get; set; }
    public string Sku { get; set; }
    public string Description { get; set; }
    public double Price { get; set; }
    public double NewPrice { get; set; }

    public override int GetHashCode()
    {
        return Id ^ (Name ?? "").GetHashCode() ^ (ModelNumber ?? "").GetHashCode() ^ (Sku ?? "").GetHashCode()^ (Description ?? "").GetHashCode() ^ Price.GetHashCode() ^ NewPrice.GetHashCode();
    }
}

我正在保存数据库中产品属性对象的哈希值以进行更改跟踪。表示哈希码会告诉我对象是否发生了变化。如果可以在app-domain之间更改哈希,那么另一种方式是什么?

2 个答案:

答案 0 :(得分:4)

  

我正在保存数据库中产品属性对象的哈希值以进行更改跟踪。

不要这样做。这就是要求哈希码随时间稳定的定义。说实话,AppDomains与此无关。

如果您需要某种 稳定的哈希,您可能希望将对象转换为稳定的二进制表示(例如,使用BinaryWriter),然后采用SHA-256哈希其中 - 因为SHA-256(和类似的加密哈希) 被设计为稳定的。

答案 1 :(得分:4)

  

我正在保存数据库中产品属性对象的哈希值以进行更改跟踪。

GetHashCode()不适合。 保证 - 实际上字符串的算法(以及结果)现在已经改变了两次,IIRC - 现在可以按照建议为每个app-domain提供不同的结果。

但更多:没有告诉您所有更改。哈希码差异告诉您不相等,但获取相同的哈希码会告诉您相等性。它不是必需的。

您需要使用可靠的已知可重复散列算法;也许是一些序列化形式的SHA1哈希,其序列化结果本身保证可靠。注意:此仍然无法保证发现所有更改,但发生冲突的可能性要小得多。