gpt4 book ai didi

c# - 一致地生成对象的哈希值

转载 作者:可可西里 更新时间:2023-11-01 08:55:51 27 4
gpt4 key购买 nike

我正在尝试获取对象的哈希值(md5 或 sha)。

我已经实现了这个: http://alexmg.com/post/2009/04/16/Compute-any-hash-for-any-object-in-C.aspx

我正在使用 nHibernate 从数据库中检索我的 POCO。
在其上运行 GetHash 时,每次从数据库中选择和水化它都是不同的。我想这是预料之中的,因为底层代理会发生变化。

无论如何,

有没有办法每次都一致地获取对象所有属性的哈希值?

我考虑过在 this.GetType().GetProperties 上使用 StringBuilder 的想法......并在其上创建哈希,但这似乎效率低下?

作为旁注,这是为了更改跟踪这些实体从一个数据库 (RDBMS) 到 NoSQL 存储(比较hash值看对象在rdbms和nosql之间有没有变化)

最佳答案

如果您不重写 GetHashCode,您只需继承 Object.GetHashCodeObject.GetHashCode 基本上只是返回实例的内存地址,如果它是一个引用对象的话。当然,每次加载一个对象时,它可能会被加载到内存的不同部分,从而导致不同的哈希码。

这是否是正确的做法值得商榷;但那是“过去”实现的内容,因此现在无法更改。

如果您想要一致的东西,那么您必须覆盖 GetHashCode 并根据对象的“值”(即属性和/或字段)创建代码。这可以像分布式合并所有属性/字段的哈希码一样简单。或者,它可以像您需要的那样复杂。 如果您正在寻找的只是区分两个不同对象的东西,那么在对象上使用唯一键可能适合您。如果您正在寻找更改跟踪,请使用唯一键哈希可能无法正常工作

我只是简单地使用所有字段的哈希码来为父对象创建一个合理分布的哈希码。例如:

public override int GetHashCode()
{
unchecked
{
int result = (Name != null ? Name.GetHashCode() : 0);
result = (result*397) ^ (Street != null ? Street.GetHashCode() : 0);
result = (result*397) ^ Age;
return result;
}
}

使用质数397是为了给一个值生成一个唯一的数字,以便更好地分配哈希码。参见 http://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/有关在哈希码计算中使用质数的更多详细信息。

当然,您可以使用反射来获取所有属性来执行此操作,但那样会更慢。或者你可以使用 CodeDOM动态生成代码以基于反射(reflect)属性并缓存该代码来生成哈希(即生成一次并在下次重新加载)。但是,这当然非常复杂,可能不值得付出努力。

MD5 或 SHA 散列或 CRC 通常基于数据 block 。如果你想要那样,那么使用每个属性的哈希码就没有意义。正如 Henk 所描述的,可能将数据序列化到内存中并以这种方式计算哈希值会更适用。

关于c# - 一致地生成对象的哈希值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12393467/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com