Как лучше всего определить, изменен ли объект? - PullRequest
4 голосов
/ 29 августа 2008

У меня есть объект, который отображается в файл cookie в виде сериализованной строки base-64. Я хочу выписать новый файл cookie только в случае внесения изменений в объект, сохраненный в файле cookie на стороне сервера.

Я хочу получить хеш-код, когда объект извлекается из файла cookie / инициализируется, и сравнить исходный хэш-код с хеш-кодом, который существует непосредственно перед отправкой заголовка файла cookie клиенту, чтобы убедиться, что я не не нужно повторно сериализовать / отправить cookie, если не были внесены изменения.

Я собирался переопределить метод .NET Object.GetHashCode(), но я не был уверен, что это лучший способ проверить, изменен ли объект.

Существуют ли другие способы проверить, изменен ли объект, или я должен переопределить метод GetHashCode().

Обновление Я решил принять ответ @ rmbarnes, так как он содержал интересное решение проблемы, и потому что я решил воспользоваться его советом в конце его поста, а не проверять наличие изменений. Мне все еще было бы интересно услышать любые другие решения, которые кто-либо может иметь к моему сценарию, однако.

Ответы [ 4 ]

2 голосов
/ 29 августа 2008

GetHashCode () всегда должен синхронизироваться с Equals (), и Equals () не обязательно проверяет наличие всех полей в вашем объекте (есть определенные ситуации, когда вы хотите, чтобы это не будь так).

Кроме того, GetHashCode () не гарантирует возвращение уникальных значений для всех возможных состояний объекта. Вполне возможно (хотя и маловероятно), что два состояния объекта могут привести к одному и тому же HashCode (который, в конце концов, имеет только возможные значения состояния int; см. Принцип Pigeonhole для получения дополнительной информации).

Если вы можете убедиться, что Equals () проверит все соответствующие поля, то вы можете клонировать объект, чтобы записать его состояние, а затем проверить его с помощью Equals () относительно нового состояния, чтобы увидеть, изменилось ли оно.

Кстати: ваше упоминание о сериализации дало мне идею. Вы можете сериализовать объект, записать его, а затем, когда вы проверите изменения объекта, повторить процесс и сравнить сериализованные значения. Это позволит вам проверять изменения состояния без необходимости вносить какие-либо изменения в код вашего объекта. Однако это не очень хорошее решение, потому что:

  1. Это, вероятно, очень неэффективно
  2. Это подвержено изменениям сериализации в объекте; Вы можете получить ложные срабатывания при изменении состояния объекта.
1 голос
/ 29 августа 2008

В конце конструктора объекта вы можете сериализовать объект в строку типа base 64 так же, как куки хранит его, и сохранить в переменной-члене.

Если вы хотите проверить, нуждается ли cookie в воссоздании, повторно сериализуйте объект и сравните эту новую строку base 64 с той, которая хранится в переменной-члене. Если он изменился, сбросьте cookie с новым значением.

Остерегайтесь ошибок - не включайте переменную-член, хранящую сериализацию base 64, в саму сериализацию. Я предполагаю, что ваш язык использует что-то вроде функции sleep () (как это делает PHP) для сериализации, так что просто убедитесь, что член не включен в эту функцию.

Это всегда будет работать, потому что вы сравниваете точное значение, которое вы сохраняете в cookie, и вам не нужно переопределять GetHashCode (), что может иметь неприятные последствия.

Все это говорит о том, что я, вероятно, просто уйду из теста и всегда сбрасываю cookie, не может быть слишком много накладных расходов по сравнению с выполнением проверки изменений и гораздо меньшей вероятностью ошибок.

0 голосов
/ 02 сентября 2008

Мне странно, почему вы хотите хранить один и тот же объект как на стороне сервера, так и на стороне клиента - особенно если вы сравниваете их в каждой поездке.

Я бы предположил, что десериализация куки-файла и сравнение его с объектом на стороне сервера по производительности эквивалентна простой повторной сериализации объекта.

Но, если бы вы захотели это сделать, я бы сравнил сериализованный объект на стороне сервера со значением cookie и обновил соответствующим образом. В худшем случае, вы сделали сериализацию ни за что. В лучшем случае вы сравнили строки.

Альтернатива десериализации и сравнения объектов имеет наихудший случай десериализации, сравнения n полей и затем сериализации. Лучший вариант - десериализация и сравнение n полей.

0 голосов
/ 29 августа 2008

Лично я бы сказал: следуйте плану, который у вас есть. Хороший хэш-код - лучший способ проверить, является ли объект «как есть». Есть множество алгоритмов хэширования, на которые вы можете посмотреть, посмотрите очевидное Страница Википедии о хэш-функциях и переходите оттуда ..

Переопределите GetHashCode и сделайте это! Просто убедитесь, что ALL элементы информации составляют часть хеша:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...