Возможно ли создать в С# словарь с истинным слабым ключом?
Я пытаюсь отключить детали для истинного WeakKeyedDictionary<,>
для С#... но я сталкиваюсь с трудностями.
Я понимаю, что это нетривиальная задача, но кажущаяся неспособность объявить WeakKeyedKeyValuePair<,>
(где GC следует только за ссылкой на значение, если ключ доступен) делает невозможным.
Я вижу две основные проблемы:
-
Каждая реализация, которую я видел до сих пор, не обрезает значения после того, как были собраны ключи. Подумайте об этом - одна из основных причин использования такого Словака - это предотвращение того, чтобы эти ценности поддерживались (а не только ключи!), Поскольку они недоступны, но здесь они оставлены с указанием сильных ссылок.
Да, добавьте/удалите из словаря достаточно, и в конечном итоге они будут заменены, но что, если вы этого не сделаете?
-
Без гипотетического WeakKeyedKeyValuePair<,>
(или другого способа сообщить GC, чтобы только отметить значение, если ключ доступен) любое значение, которое относится к нему, никогда не будет собрано. Это проблема при сохранении произвольных значений.
Проблема 1 может быть решена довольно неидеальным/хакерским способом: используйте GC Notifications, чтобы дождаться завершения полного GC, а затем перейдите и обрезайте словарь в другом потоке. Этот я полуоочень с.
Но проблема 2 меня в тупике. Я понимаю, что это легко противопоставляется "так не делай этого", но мне это интересно: эта проблема даже разрешима?
Ответы
Ответ 1
Посмотрите ConditionalWeakTable < TKey, TValue > Класс.
Позволяет компиляторам динамически присоединять поля объектов к управляемым объектам.
Это, по сути, словарь, где ключ и значение WeakReference, и значение сохраняется в памяти, пока ключ жив.
Внимание! Этот класс не использует GetHashCode
и Equals
для сравнения равенств, он использует ReferenceEquals
.