【发布时间】:2014-09-03 11:30:16
【问题描述】:
据this Eric博客,
规则:GetHashCode 的消费者不能依赖它随着时间的推移或跨应用程序域而保持稳定。 假设您有一个 Customer 对象,该对象具有一堆字段,例如名称、地址等。如果您在两个不同的进程中创建两个具有完全相同数据的此类对象,则它们不必返回相同的哈希码。如果您在星期二在一个进程中创建这样的对象,然后将其关闭,然后在星期三再次运行该程序,则哈希码可能会有所不同。 这在过去曾咬人。 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();
}
}
我将产品属性对象的哈希值保存在数据库中以进行更改跟踪。意味着哈希码会告诉我对象是否改变。如果可以在应用程序域之间更改哈希,那么另一种方式是什么?
【问题讨论】:
-
这不是
GetHashCode的用途。事实上,这正是您不应该使用它的目的。为什么不使用version列或类似的东西呢? -
GetHashCode的值在对象创建后不允许更改。您不能将其基于可变的字段/属性。唯一可以将哈希码基于属性的情况是当这些属性是只读的并在构造函数中设置时。如果哈希码发生变化,字典之类的东西就会失败。 -
@Enigmativity,我说的是不同 AppDomain(或进程)上的相同对象或在不同日期打开 exe。
-
@user960567 - 是的,我知道。但我说的是您在问题中发布的代码。以这种方式实现
GetHashCode是错误的。