在二进制序列化(二进制)期间是否有可能保存对象的哈希码?

时间:2011-03-31 18:58:24

标签: c# serialization binary-serialization

我希望能够通过哈希码比较对象。

每个例子,一个是对象本身,另一个是序列化(二进制),然后是对象的恢复版本。

如何在序列化(二进制)对象中保存哈希?

3 个答案:

答案 0 :(得分:3)

为什么要序列化哈希码?相反,您应该在对象中提供GetHashCode()Equals()的正确实现,允许您根据它们的值比较两个对象 - 如果两个对象相等,则它们的哈希码必须匹配。因此,一旦对对象进行了反序列化,就可以对其使用GetHashCode()并将其与其他对象进行比较。请注意,两个哈希码匹配的事实不足以确定相等性,它们可能仍然不同 - 您必须调用Equals()的正确实现来确定相等。

如果您只想比较对象中的自定义字段并且完全比较可能过于昂贵(即大型二进制数组),那么在字段上生成MD5哈希(即使用MD5CryptoServiceProvider.ComputeHash())可能是有意义的并将其存储在对象本身内,然后将像任何其他对象属性一样进行序列化。

答案 1 :(得分:3)

小心!

.Net对象的默认HashCode经常在程序的运行时实例之间更改。

换句话说,如果你的程序将对象A序列化为完成哈希码,对光盘,则程序终止,稍后重新启动,并从光盘反序列化对象A,(或者在运行时创建一个相同的对象A,它将具有不同的哈希码,而不是存储的哈希码。

这部分是因为默认的哈希码来自对象的垃圾收集器信息。在新的程序实例中,GC将具有不同的信息,因此具有不同的哈希码。

如果您编写自己的GetHashCode,则可以创建跨进程一致的哈希码。但是你需要注意一个陷阱。

答案 2 :(得分:1)

是否有任何信息可用于判断哪些对象是从哪些原件序列化和反序列化的?如果是这样,那么您可以覆盖GetHashCode()以根据该信息计算哈希码。

如果没有,您可以通过为每个新创建的对象分配UUID来合成生成一个。将该值与其他数据一起序列化,以使重建的对象具有相同的UUID。然后,您可以简单地重写GetHashCode()以返回该UUID的哈希码。 (如果您正在寻找的是一种参考平等的修改版本,那应该可以完成工作。)