5

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

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

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

有没有其他方法可以检查对象是否被修改,或者我应该覆盖该GetHashCode()方法。

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

4

4 回答 4

2

GetHashCode() 应该始终与 Equals() 同步,并且 Equals() 不一定保证检查对象中的所有字段(在某些情况下,您希望不是这种情况)。

此外,GetHashCode() 不能保证为所有可能的对象状态返回唯一值。可以想象(尽管不太可能)两个对象状态可能导致相同的 HashCode(毕竟,它确实只有一个 int 值的可能状态;有关更多详细信息,请参阅鸽笼原则)。

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

BTW:你提到的序列化给了我一个想法。您可以序列化对象,记录它,然后当您检查对象更改时,重复该过程并比较序列化值。这将使您无需对对象进行任何代码更改即可检查状态更改。但是,这不是一个很好的解决方案,因为:

  1. 这可能非常低效
  2. 容易发生对象的序列化变化;您可能会在对象状态更改时得到误报。
于 2008-08-29T17:39:46.303 回答
1

在对象的构造函数结束时,您可以将对象序列化为 base 64 字符串,就像 cookie 存储它一样,并将其存储在成员变量中。

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

注意问题 - 不要在序列化本身中包含存储 base 64 序列化的成员变量。我认为您的语言使用类似 sleep() 函数(PHP 是如何做到的)来序列化自身,所以只需确保该成员不包含在该函数中。

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

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

于 2008-08-29T18:02:04.160 回答
0

我个人会说按照你的计划去做。一个好的哈希码是查看对象是否“原样”的最佳方法。你可以查看大量的哈希算法,查看明显的Wikipedia页面哈希函数并从那里开始..

覆盖 GetHashCode 并继续努力!只需确保信息的所有元素都构成哈希的一部分 :)

于 2008-08-29T17:40:27.270 回答
0

对我来说似乎很奇怪,为什么您要在服务器端和客户端存储相同的对象 - 特别是如果您在每次旅行中都比较它们。

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

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

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

于 2008-09-01T20:24:35.790 回答