递归调用返回一个List,返回类型导致我的问题

时间:2009-10-01 13:54:23

标签: c# recursion

我有一个递归方法,它返回我的类别,并检查其子类别。

所以看起来像:

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 个答案:

答案 0 :(得分:42)

目前你没有显示任何实际上在列表中添加单个类别的内容......我假设你在递归时想要添加Get(categoryId)的结果·

Preet的解决方案肯定会有效,但这里可以避免创建所有额外的列表:

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吗?在您获取整个类别之前,每个孩子是否只包含其ID?

答案 1 :(得分:12)

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

      }

并且不要忘记

return list;

答案 2 :(得分:2)

我认为这个linq版本可以避免创建列表的开销:

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

如果需要,您可以随时在返回的IEnumerable上调用ToList()。

答案 3 :(得分:2)

之前我遇到过同样的问题。这是我解决它的方式:

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

    foreach(ProductCategory cat in ParentCategory.ChildCategories)
    {
        GetAllChildCategories(cat);
    }
}

答案 4 :(得分:0)

这是Jon Skeet使用本地方法(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);
            }
        }
    }