如何最好地判断一个对象是否被修改?

6
我有一个映射到cookie的对象,以序列化的base-64字符串形式表示。仅当服务器端存储的cookie中的对象发生更改时,我才想要写出新的cookie。
我的想法是在从cookie/初始化中提取对象时获取哈希码,并将原始哈希码与发送cookie头之前存在的哈希码进行比较,以确保除非进行更改,否则不必重新序列化/发送cookie。
我本来想覆盖.NET的Object.GetHashCode()方法,但我不确定这是否是检查对象是否被修改的最佳方法。
是否有其他方法可以检查对象是否被修改,或者应该覆盖GetHashCode()方法。
更新:我决定接受@rmbarnes的答案,因为它提供了解决问题的有趣方法,并且因为我决定使用他在文章末尾的建议而不是检查修改。然而,如果有人对我的情况有任何其他解决方案,我仍然很感兴趣。
4个回答

3
GetHashCode() 应该始终与 Equals() 保持同步,而 Equals() 不一定保证检查对象中的所有字段(在某些情况下,你可能不希望如此)。
此外,GetHashCode() 并不能保证为所有可能的对象状态返回唯一值。虽然可能性很小,但两个对象状态可能导致相同的哈希码(毕竟,它只有一个 int 值得可能状态;详情请参见鸽巢原理)。
如果你可以确保 Equals() 检查了所有适当的字段,则可能会复制对象以记录其状态,然后使用 Equals() 将其与新状态进行比较以查看是否已更改。
顺便说一句:你提到序列化给了我一个想法。你可以序列化对象、记录它,然后在检查对象更改时重复这个过程并比较序列化的值。这将让你检查状态更改而无需对对象进行任何代码更改。然而,这不是一个很好的解决方案,因为:
  1. 这可能非常低效。
  2. 它容易受到对象序列化更改的影响;你可能会在对象状态更改时得到错误的结果。

1
在对象的构造函数末尾,您可以将对象序列化为一个Base64字符串,就像cookie存储它一样,并将其存储在成员变量中。
当您想要检查cookie是否需要重新创建时,请重新序列化对象,并将此新的Base64字符串与存储在成员变量中的字符串进行比较。如果已更改,则使用新值重置cookie。
注意陷阱-不要在序列化本身中包含存储Base64序列化的成员变量。我假设您的语言使用类似于sleep()函数(PHP的方式)来进行序列化,因此只需确保该成员未包含在该函数中即可。
这将始终起作用,因为您正在比较您将保存在cookie中的确切值,而且不需要覆盖GetHashCode(),因为这可能会产生不良后果。
话虽如此,我可能会放弃测试并始终重置cookie,在与执行更改检查相比,它的开销不会太大,并且出错的可能性要小得多。

0

我个人认为你应该按照你的计划去做。一个好的哈希码是判断对象是否“原样”的最佳方式。有很多哈希算法可以参考,可以查看维基百科关于哈希函数的页面并从那里开始。

重写GetHashCode并开始吧!只需确保所有信息元素都构成哈希的一部分即可 :)


0

我觉得很奇怪,为什么你想要在服务器端和客户端都存储同一个对象,特别是如果你在每次传输时都要进行比较。

我猜反序列化 cookie 并将其与服务器端对象进行比较,在性能上相当于再次序列化对象。

但是,如果你想这样做,我会将序列化的服务器端对象与 cookie 的值进行比较并相应地更新。最坏的情况是你白白进行了序列化。最好的情况是你进行了字符串比较。

另一种选择是反序列化和比较对象,最坏的情况是反序列化、比较 n 个字段,然后序列化。最好的情况是反序列化和比较 n 个字段。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接