Преобразование Object.GetHashCode () в Guid - PullRequest
2 голосов
/ 05 декабря 2011

Мне нужно назначить guid для объектов для управления состоянием при запуске и завершении работы приложения Похоже, я могу сохранить значения поиска в словаре, используя

dictionary<int,Guid>.Add(instance.GetHashCode(), myGUID());

Есть ли здесь потенциальные проблемы, о которых следует знать?

Примечание

Это НЕ должно сохраняться между запусками выполнения, только guid, как это

  • создать объект
  • gethashcode (), связать с новым или старым guid
  • перед завершением работы приложения, gethashcode () и руководство поиска для update () или вставки () в механизм сохранения состояния ИСПОЛЬЗУЯ GUID

    Единственное предположение, что gethashcode () остается непротиворечивым во время выполнения процесса

    также gethashcode () вызывается для того же типа объекта (производного от окна)

Обновление 2 - вот большая картинка

  • создать конечный автомат для хранения информации о пользовательских элементах управления WPF (позже в коде UC) между запусками
  • типы пользовательских элементов управления могут изменяться с течением времени (добавлены / удалены)
  • в самом первом запуске нет предшествующего состояния, пользователь взаимодействует с подмножеством UC и изменяет их состояние, которое необходимо воссоздать при перезапуске приложения
  • этот снимок состояния делается при нормальном завершении работы приложения
  • также может быть несколько экземпляров типа UC
  • при завершении работы каждому экземпляру назначается гид и сохраняется вместе с информацией о типе и информацией о состоянии
  • все эти направляющие также хранятся в коллекции
  • при перезапуске для каждого guid создайте объект, сохраните ref / guid, восстановите состояние для каждого экземпляра, чтобы приложение выглядело точно так же, как и раньше
  • пользователь может добавлять или удалять экземпляры / типы UC и иным образом взаимодействовать с системой
  • при выключении состояние сохраняется снова
  • В настоящее время можно удалить / удалить все предыдущие состояния и вставить новую информацию о состоянии в постоянный слой (sql db)
  • при наблюдении / анализе с течением времени выясняется, что многие экземпляры остаются согласованными / статичными и не меняются - поэтому их состояние не нужно удалять / вставлять снова, поскольку информация о состоянии теперь достаточно велика и хранится поверх местный дБ
  • поэтому сохраняется только дельта изменения
  • Чтобы вычислить дельту, необходимо отслеживать эталонные времена жизни
  • в данный момент хранится как List<WeakReference> при запуске
  • при выключении, перебирайте этот список и фактический UC, присутствующий на экране, соответственно добавляйте / обновляйте / удаляйте ключи
  • отправить дельту на постоянство

Надеюсь, вышесказанное прояснит.

Так что теперь вопрос - почему бы просто не сохранить HashCode (только для usercontrol) вместо WeakReference и исключить тест для нулевой ссылки, пока перебирая список

обновление 3 - спасибо всем, собираюсь наконец использовать слабую ссылку

Ответы [ 5 ]

8 голосов
/ 06 декабря 2011

Используйте GetHashCode для балансировки хеш-таблицы . Вот для чего это. Не используйте его для других целей, для которых он не предназначен; это очень опасно

8 голосов
/ 05 декабря 2011

Похоже, вы предполагаете, что хеш-код будет уникальным. Хэш-коды не работают так. Обратитесь к сообщению Эрика Липперта в блоге на Руководства и правила для GetHashCode для получения более подробной информации, но в основном вы должны делать только те предположения, которые гарантированы для типов с хорошим поведением - а именно, если два объекта имеют разные хеш-коды, они Вы определенно неравны. Если они имеют одинаковый хэш-код, они могут быть равными, но могут не совпадать.

РЕДАКТИРОВАТЬ: Как отмечалось, вы также не должны сохранять хэш-коды между запусками выполнения. Там нет гарантии, что они будут стабильны при перезапусках. Не совсем понятно, что именно вы делаете, но это не очень хорошая идея.

РЕДАКТИРОВАТЬ: Хорошо, теперь вы заметили, что это не будет постоянным, так что это хорошее начало - но вы все еще не имели дело с возможностью коллизий хеш-кода. Почему вы вообще хотите позвонить GetHashCode()? Почему бы просто не добавить ссылку на словарь?

2 голосов
/ 05 декабря 2011

Быстрое и простое исправление выглядит как

var dict = new Dictionary<InstanceType, Guid>();
dict.Add(instance, myGUID());

Конечно, вам нужно правильно реализовать InstanceType.Equals, если это еще не сделано.(Или реализовать IEQuatable<InstanceType>)

0 голосов
/ 07 декабря 2011

Так как это для элементов управления WPF, почему бы просто не добавить Guid в качестве зависимого устройства?Похоже, вы уже перебираете пользовательские элементы управления, чтобы получить их хэш-коды, так что это, вероятно, будет более простой метод.

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

0 голосов
/ 05 декабря 2011

Возможные проблемы, о которых я могу подумать:

  • Коллизии хеш-кода могут дать вам дублирующие ключи словаря
  • Различные алгоритмы хеширования объекта могут дать вам один и тот же хеш-код для двух функционально разных объектов; вы не знаете, с каким объектом вы работаете
  • Эта реализация подвержена неоднозначности (как описано выше); вам может потребоваться хранить больше информации о ваших объектах, чем просто их хэш-коды.

Примечание - Джон сказал это более элегантно ( см. Выше )

...