我希望能够通过哈希码比较对象。
例如,一个是对象本身,另一个是序列化(二进制),然后是对象的恢复版本。
如何将哈希保存在序列化(二进制)对象中?
我希望能够通过哈希码比较对象。
例如,一个是对象本身,另一个是序列化(二进制),然后是对象的恢复版本。
如何将哈希保存在序列化(二进制)对象中?
为什么必须序列化哈希码?相反,您应该在对象中提供适当的实现GetHashCode()
,Equals()
允许您根据它们的值比较两个对象 - 如果两个对象相等,则它们的哈希码必须匹配。所以一旦你反序列化了对象,你就可以GetHashCode()
在它上面使用它并将它与另一个对象进行比较。请注意,两个哈希码匹配的事实不足以确定相等性,它们可能仍然不同 - 您必须调用正确的实现Equals()
来确定相等性。
如果您只想比较对象中的自定义字段并且完全比较可能太昂贵(即大型二进制数组),那么MD5CryptoServiceProvider.ComputeHash()
在字段上生成 MD5 哈希(即 with )并将其存储在对象本身中可能是有意义的,然后它将像任何其他对象属性一样被序列化。
警惕!
.Net 对象的默认 HashCode 经常在程序的运行时实例之间更改。
换句话说,如果您的程序将A
带有哈希码的 object 序列化到磁盘,然后程序终止,然后重新启动,并A
从磁盘反序列化 object (或在运行时创建相同的对象A
),它将具有与存储的不同的哈希码。
这部分是因为默认哈希码来自对象的垃圾收集器信息。在一个新的程序实例中,GC 会有不同的信息,因此会有不同的哈希码。
如果您自己编写GetHashCode
,则可以制作跨进程一致的哈希码。但是这里有一个陷阱你需要注意。
是否有任何信息可以用来判断哪些对象是从哪些原件序列化和反序列化的?如果是这样,那么您可以覆盖 GetHashCode() 以根据该信息计算哈希码。
如果没有,您可以通过为每个新创建的对象分配一个 UUID 来综合生成一个。将该值与其他数据一起序列化,以便重建的对象具有相同的 UUID。然后,您可以简单地覆盖 GetHashCode() 以返回该 UUID 的哈希码。(如果您正在寻找的是一种修改版本的引用相等,那应该可以完成这项工作。)