Можно ли создать по-настоящему слабый словарь в C#?

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

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

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

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

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

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

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

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

1 ответ

Решение

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

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

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

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

Другие вопросы по тегам