【问题标题】:Recursive call return a List, return type causing me issues递归调用返回一个列表,返回类型导致我出现问题
【发布时间】:2022-04-05 22:24:50
【问题描述】:

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

这是我的代码:

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 对象,但GetAllChildCats() 返回List&lt;Category&gt;

我应该如何解决这个问题?

【问题讨论】:

    标签: c# recursion


    【解决方案1】:

    目前您还没有显示任何实际上将单个类别添加到列表中的内容...我假设当您递归时,您也想添加 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?

    【讨论】:

      【解决方案2】:
         foreach(Category cat in c.ChildCategories)
            {
                    list.AddRange( GetAllChildCats(cat.CategoryID) )
      
            }
      

      别忘了

      return list;
      

      【讨论】:

      • 目前这将始终返回一个空列表...有关更多详细信息,请参阅我的答案。
      【解决方案3】:

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

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

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

      【讨论】:

      • 你很热心。 .SelectMany 递归非常慢。
      【解决方案4】:

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

      public void GetAllChildCategories(ProductCategory ParentCategory)
      {
          ParentCategory.ChildCategories = GetChildCategories(ParentCategory.ID);
      
          foreach(ProductCategory cat in ParentCategory.ChildCategories)
          {
              GetAllChildCategories(cat);
          }
      }
      

      【讨论】:

        【解决方案5】:

        这是 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);
                    }
                }
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-01-18
          • 2019-07-06
          • 1970-01-01
          • 2010-12-08
          • 2020-09-09
          • 2013-02-26
          • 2015-06-25
          相关资源
          最近更新 更多