Возможно ли создать в С# словарь с истинным слабым ключом?

Я пытаюсь отключить детали для истинного WeakKeyedDictionary<,> для С#... но я сталкиваюсь с трудностями.

Я понимаю, что это нетривиальная задача, но кажущаяся неспособность объявить WeakKeyedKeyValuePair<,> (где GC следует только за ссылкой на значение, если ключ доступен) делает невозможным.

Я вижу две основные проблемы:

  • Каждая реализация, которую я видел до сих пор, не обрезает значения после того, как были собраны ключи. Подумайте об этом - одна из основных причин использования такого Словака - это предотвращение того, чтобы эти ценности поддерживались (а не только ключи!), Поскольку они недоступны, но здесь они оставлены с указанием сильных ссылок.

    Да, добавьте/удалите из словаря достаточно, и в конечном итоге они будут заменены, но что, если вы этого не сделаете?

  • Без гипотетического WeakKeyedKeyValuePair<,> (или другого способа сообщить GC, чтобы только отметить значение, если ключ доступен) любое значение, которое относится к нему, никогда не будет собрано. Это проблема при сохранении произвольных значений.

Проблема 1 может быть решена довольно неидеальным/хакерским способом: используйте GC Notifications, чтобы дождаться завершения полного GC, а затем перейдите и обрезайте словарь в другом потоке. Этот я полуоочень с.

Но проблема 2 меня в тупике. Я понимаю, что это легко противопоставляется "так не делай этого", но мне это интересно: эта проблема даже разрешима?

Ответ 1

Посмотрите ConditionalWeakTable < TKey, TValue > Класс.

Позволяет компиляторам динамически присоединять поля объектов к управляемым объектам.

Это, по сути, словарь, где ключ и значение WeakReference, и значение сохраняется в памяти, пока ключ жив.

Внимание! Этот класс не использует GetHashCode и Equals для сравнения равенств, он использует ReferenceEquals.