#c# #recursion
#c# #рекурсия
Вопрос:
Кажется, я не могу разобраться в этом. Мне нужно собрать некоторые тестовые данные для построения древовидного меню, но я либо получаю ошибку stackverflow, потому что она просто продолжается, либо я получаю только первый уровень дочерних элементов. Вот код, который у меня сейчас есть:
private MenuItem _menuItem;
private int _start = 1;
private const int Stop = 5;
public void BuildMenu()
{
var numberOfChildren = new Random((int) DateTime.Now.Ticks).Next(3, 40);
AutoMapper.Mapper.CreateMap<MenuItem, MenuItemDto>().ConvertUsing<MenuItemConverter>();
_menuItem = new MenuItem() {Id = Guid.NewGuid(), Name = "Main Menu"};
_menuItem.ChildMenuItems = BuildChildItems(_menuItem, numberOfChildren);
var menuDto = AutoMapper.Mapper.Map<MenuItem, MenuItemDto>(_menuItem);
}
public ICollection<MenuItem> BuildChildItems(MenuItem parentMenuItem, int numberOfChildren)
{
var childItems = new Collection<MenuItem>();
_start = 1;
for (var i = 0; i <= numberOfChildren; i )
{
var childItem = new MenuItem()
{
Id = Guid.NewGuid(),
ParentItemId = parentMenuItem.Id,
Parentitem = parentMenuItem,
Name = "Child Menu Item " DateTime.Now
};
if (_start != Stop)
{
childItem.ChildMenuItems = BuildChildItems(childItem, numberOfChildren);
}
childItems.Add(childItem);
}
return childItems;
}
public class MenuItem
{
public Guid Id { get; set; }
public string Name { get; set; }
public Guid? ParentItemId { get; set; }
public MenuItem Parentitem { get; set; }
public ICollection<MenuItem> ChildMenuItems { get; set; }
}
Пока это работает, вы заметите переменные _start и Stop . Я вставил их, поэтому я не получаю stackoverflow, но, очевидно, именно поэтому я получаю только 1-й уровень каждого из заполненных дочерних элементов. Я полагаю, мне нужно будет отслеживать, на каком уровне я нахожусь, но не уверен, как это отслеживать. Не уверен, почему я сегодня рисую пробел….
Ответ №1:
Это дает представление, а не фактически рассматривает вашу конкретную объектную модель! Есть int, который представляет количество уровней, на которые вы хотите перейти. Отправьте это в метод, уменьшайте его при каждой рекурсии, пока оно не станет равным нулю.
public void BuildChildItems(MenuItem parentMenuItem, int numberOfChildren, int level)
{
if(level == 0) return;
var results_for_this_level = create_results_for_this_level();
parentMenuItem.Add(results_for_this_level);
foreach(sibling in results_for_this_level)
{
BuildChildItems(sibling, numberofChildren, level-1) //note the decrement of level here
}
}