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

时间:2008-08-29 17:30:15

标签: c# .net

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

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

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

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

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

4 个答案:

答案 0 :(得分:2)

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

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

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

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

  1. 这可能非常低效
  2. 它很容易在对象中进行序列化更改;你可能会对对象状态的变化产生误报。

答案 1 :(得分:1)

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

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

注意陷阱 - 不要在序列化本身中包含存储base 64序列化的成员变量。我假设你的语言使用类似sleep()函数的东西(PHP就是这样做的)来序列化自己,所以只要确保该成员不包含在该函数中。

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

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

答案 2 :(得分:0)

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

覆盖GetHashCode并继续使用!只需确保 ALL 信息的元素构成哈希的一部分:)

答案 3 :(得分:0)

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

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

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

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