Вы можете иметь объект Building
, состоящий из свойства NeighbourBuildings
, который представляет собой совокупность всех зданий, непосредственно связанных с этим зданием, и объект * ConnectedBuildings
, который представляет собой совокупность всех зданий, напрямую и косвенно связанных в это здание.
Затем при вызове метода получения ConnectedBuildings
вы возвращаете новую коллекцию, которая содержит здание плюс совокупность ConnectedBuildings
коллекций всех ConnectedBuildings
.
Тогда вы заметите, что рекурсив l oop никогда не останавливается, потому что он перемещается туда-сюда между зданиями. Например: B подключен к C, который подключен к B, который подключен к C, et c. Таким образом, чтобы решить эту проблему, вам нужно добавить понятие родителя : каждое здание станет родителем или дочерним элементом другого здания. Каждое здание имеет только одного родителя, но столько детей, сколько необходимо. Таким образом, вы начинаете строить дерево и вызывать только дочерние здания родительского здания, но никак не наоборот, так что ваш рекурсивный l oop завершится, как только дочернее здание сделает не имеет детей.
Некоторые предлагаемые архитектуры:
ParentBuilding
= родитель этого здания. ChildBuildings
= коллекция дочерних зданий, которые подключены к этому зданию. AllChildBuildings
= ChildBuildings.Select(building =>
building.AllChildBuildings)
ConnectedBuildings
= ParentBuilding
+ ChildBuildings
(не обязательно, но чтобы помочь вам понять архитектуру)
Каждый узел (здесь здание) будет содержать ссылку на все узлы, для которых он является прямым или косвенным родителем. В зависимости от требуемой производительности, вы можете рассмотреть возможность расчета дерева только один раз или каждый раз, когда вы делаете вызов.
Наконец, убедитесь, что у вас никогда не будет круга, где A является родителем B , который является родителем C, который является родителем A: у вас больше не будет дерева, и рекурсивный вызов снова будет бесконечным.