Рекурсивный вызов возвращает список, тип возврата вызывает у меня проблемы - PullRequest
15 голосов
/ 01 октября 2009

У меня есть рекурсивный метод, который возвращает мне категории и проверяет его подкатегории.

Так это выглядит так:

public List<Category> GetAllChildCats(int categoryid)
{
      List<Category> list = new List>Category>();

      Category c = Get(categoryid);

      foreach(Category cat in c.ChildCategories)
      {
              list.Add( GetAllChildCats(cat.CategoryID) )

      }

}

Это не удалось, потому что вызов list.add ожидает объект Category, но он возвращает еще один List, как мне обойти это?

Ответы [ 5 ]

42 голосов
/ 01 октября 2009

В настоящее время вы не показали ничего, что фактически добавляло бы одну категорию в список ... Я предполагаю, что когда вы повторяете, вы хотите добавить и результаты Get(categoryId).

Решение Преета, безусловно, будет работать, но есть альтернатива, которая позволяет избежать создания всех дополнительных списков:

public List<Category> GetAllChildCats(int categoryId)
{
    List<Category> ret = new List<Category>();
    GetAllChildCats(categoryId, ret);
    return ret;
}

private void GetAllChildCats(int categoryId, List<Category> list)
{
    Category c = Get(categoryid);
    list.Add(c);

    foreach(Category cat in c.ChildCategories)
    {
        GetAllChildCats(cat.CategoryID, list);
    }
}

Это создает единый список и добавляет к нему элементы по ходу.

Одно замечание: если у вас уже есть дочерние Category объекты, вам действительно нужно снова вызывать Get? Каждый ребенок содержит только свой идентификатор, пока вы не получите всю категорию?

12 голосов
/ 01 октября 2009
   foreach(Category cat in c.ChildCategories)
      {
              list.AddRange( GetAllChildCats(cat.CategoryID) )

      }

и не забудьте

return list;
2 голосов
/ 14 июля 2012

У меня была такая же проблема раньше. Вот как я решил это:

public void GetAllChildCategories(ProductCategory ParentCategory)
{
    ParentCategory.ChildCategories = GetChildCategories(ParentCategory.ID);

    foreach(ProductCategory cat in ParentCategory.ChildCategories)
    {
        GetAllChildCategories(cat);
    }
}
2 голосов
/ 01 октября 2009

Я думаю, что эта версия linq позволит вам избежать затрат на создание списка:

public IEnumerable<Category> GetAllChildCats(int categoryid)
{
    Category c = Get(categoryid);
    return new[] { c }.Concat(c.ChildCategories.SelectMany(cat => GetAllChildCats(cat)));
}

Вы всегда можете вызвать ToList () для возвращенного IEnumerable, если вам это нужно.

0 голосов
/ 22 мая 2018

Вот модифицированная версия ответа Джона Скита с использованием локального метода (C # 7):

    public List<Category> GetAllChildCats(int rootId)
    {
        List<Category> list = new List<Category>();
        Traverse(rootId);
        return list;

        void Traverse(int categoryId)
        {
            Category c = Get(categoryId);
            list.Add(c);

            foreach (Category cat in c.ChildCategories)
            {
                Traverse(cat.CategoryID);
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...