Можно ли создать по-настоящему слабый словарь в C #? - PullRequest
22 голосов
/ 09 декабря 2011

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

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

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

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

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

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

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

Но проблема 2 поставила меня в тупик.Я понимаю, что этому легко противостоит «так не делай этого», но меня удивляет - можно ли вообще решить эту проблему?

1 Ответ

28 голосов
/ 09 декабря 2011

Посмотрите на ConditionalWeakTableКласс .

Включает компиляторы для динамического присоединения полей объекта к управляемым объектам.

По сути это словарь, в котором ключ и значение являются WeakReference , и значение сохраняется, пока ключ активен.

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

...