根据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之间更改哈希,那么另一种方式是什么?
答案 0 :(得分:4)
不要这样做。这就是要求哈希码随时间稳定的定义。说实话,AppDomains与此无关。我正在保存数据库中产品属性对象的哈希值以进行更改跟踪。
如果您需要某种 稳定的哈希,您可能希望将对象转换为稳定的二进制表示(例如,使用BinaryWriter
),然后采用SHA-256哈希其中 - 因为SHA-256(和类似的加密哈希) 被设计为稳定的。
答案 1 :(得分:4)
我正在保存数据库中产品属性对象的哈希值以进行更改跟踪。
GetHashCode()
不适合。 不保证 - 实际上字符串的算法(以及结果)现在已经改变了两次,IIRC - 现在可以按照建议为每个app-domain提供不同的结果。
但更多:没有告诉您所有更改。哈希码差异告诉您不相等,但获取相同的哈希码不会告诉您相等性。它不是必需的。
您需要使用可靠的已知可重复散列算法;也许是一些序列化形式的SHA1哈希,其序列化结果本身保证可靠。注意:此仍然无法保证发现所有更改,但发生冲突的可能性要小得多。