У меня была похожая модель с быстрым доступом к вышестоящим экземплярам Node
в ориентированных ациклических графах. Node
имеет слабую ссылку на своего непосредственного родителя. Node
имеет свойство для получения Root ..., которое пытается вернуть Root своего родителя. Если нет родителя, то этот узел является корнем. Корень основывается исключительно на сдерживании. Обратите внимание, что родительский элемент не является коллекцией ... потому что иногда дочерний узел отсутствует даже в коллекции. Что-то более или менее похожее ...
public abstract class Node
{
WeakReference<Node> parent;
public Node Root
{
get { return Parent?.Root ?? this; }
}
public Node Parent
{
get
{
if ( parent != null )
{
if ( parent.TryGetTarget( out Node parentNode ) )
{
return parentNode;
}
}
return this;
}
internal set { /*...*/ } //--> if you're brave...
}
}
Редактировать
Относительно WeakReferences ... одна из вещей, которую могут иметь наши графы, это ссылки на узлы в других графах. У нас есть служба распознавания узлов, которая будет извлекать эти другие узлы. Эти внешние ссылки представлены значением идентичности (GUID
или Long
) и связанной слабой ссылкой. Таким образом, мы можем загрузить указанный узел по мере необходимости, но не хранить его дольше, чем необходимо. Средство распознавания поддерживает кэш LRU узлов, разрешенных таким образом.
Если такая разрешенная ссылка должна разрешать своего родителя, существует аналогичный механизм, позволяющий зависимому узлу разрешать своего родителя. Даже собранные дочерние узлы узла могут быть лениво загружены через службу распознавания (хотя есть аннотации, которые сообщают нашей платформе, когда выполнять отложенную загрузку, а когда нет).
Итак, слабые ссылки помогают во всех этих случайно разрешенных сценариях. Э-э ... точнее, они помогают нам не портить сбор мусора в таких сценариях.
В некоторых аналитических сценариях у нас появляются и появляются сотни тысяч узлов. Я мог представить аналогичную динамику в химическом моделировании.