判断对象是否被修改的最佳方法是什么?

时间:2020-03-05 18:45:06  来源:igfitidea点击:

我有一个对象,该对象作为序列化的base-64字符串映射到cookie。我只想写出一个新的cookie,如果对服务器端存储在cookie中的对象进行了更改。

我想做的是,当从Cookie /初始化对象中提取对象时获得哈希码,然后将原始哈希码与将Cookie标头发送给客户端之前存在的哈希码进行比较,以确保没有重新序列化/发送cookie,除非进行了更改。

我打算重写.NET的Object.GetHashCode()方法,但是我不确定这是否是检查对象是否被修改的最佳方法。

还有其他方法可以检查对象是否被修改,还是应该重写GetHashCode()方法。

更新我决定接受@rmbarnes的答案,因为它对问题有一个有趣的解决方案,并且因为我决定在他的帖子结尾使用他的建议,而不是检查修改。但是,我仍然有兴趣听到任何其他人可能对我的方案有任何解决方案。

解决方案

回答

GetHashCode()应该始终与Equals()保持同步,并且不一定要确保Equals()会检查对象中的所有字段(在某些情况下,我们不希望这样做)。

此外,不能保证GetHashCode()返回所有可能的对象状态的唯一值。可以想象(尽管不太可能),两个对象状态可能导致相同的HashCode(毕竟,它仅具有int的可能状态;有关更多详细信息,请参见Pigeonhole原理)。

如果可以确保Equals()检查所有适当的字段,则可以克隆该对象以记录其状态,然后针对新状态使用Equals()对其进行检查以查看其是否已更改。

顺便说一句:我们提到的序列化给了我一个主意。我们可以序列化对象,进行记录,然后在检查对象更改时,重复该过程并比较序列化的值。这样一来,我们无需检查对象的任何代码即可检查状态更改。但是,这不是一个很好的解决方案,因为:

  • 这可能效率很低
  • 对象中的序列化更改很容易;我们可能会在对象状态更改上得到误报。

回答

我个人会说要按照计划进行。.好的哈希码是查看对象是否"按原样"的最佳方式。.我们可以查看大量的哈希算法,请查看明显的Wikipedia页面。哈希函数,然后从那里去。

覆盖GetHashCode并继续使用它!只要确保信息的所有元素都构成哈希的一部分即可:)

回答

在对象的构造函数的末尾,我们可以将对象序列化为基本64字符串,就像cookie存储它一样,然后将其存储在成员变量中。

当我们要检查是否需要重新创建cookie时,请重新序列化该对象,并将此新的base 64字符串与成员变量中存储的字符串进行比较。如果已更改,请使用新值重置Cookie。

当心陷阱,不要在序列化本身中包含存储base 64序列化的成员变量。我假设语言使用了sleep()函数(即PHP的工作方式)之类的东西来对其自身进行序列化,因此只需确保该函数中不包含该成员即可。

这将始终有效,因为我们正在比较要保存在Cookie中的确切值,并且不需要覆盖GetHashCode(),这听起来可能会带来讨厌的后果。

所有这些,我可能只是放弃测试并始终重置cookie,与进行更改检查相比,其中的开销不会太大,而且错误发生的可能性也要小得多。

回答

令我感到奇怪的是,为什么要在服务器端和客户端都存储相同的对象,特别是如果我们在每次旅行中都将它们进行比较时。

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

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

另一种方法是反序列化和比较对象,最糟糕的情况是反序列化,比较n个字段然后进行序列化。最好的情况是反序列化和比较n个字段。