【问题标题】:Loosing values when coming out of recursion退出递归时丢失值
【发布时间】:2014-10-03 10:26:52
【问题描述】:

我对递归比较陌生。我遇到了一个奇怪的情况。正如您在下面看到的,我正在为一个复杂的部门填充员工。一个复杂部门下可以有一个或多个简单部门和复杂部门。它还有一个员工集合(列表)。当我通过这个进行调试时,第一个部门很复杂,所以它会递归,在那里我看到员工被正确填充并且员工集合计数为 2,但是当它从递归调用中出来,员工收集计数再次设置为零。关于我在这里可能做错的任何想法?

private void PopulateEmployees(ComplexDepartment complex)
{            
    foreach (var dep in complex.Departments)
    {                
        if (dep is SimpleDepartment)
        {
             var simple = dep as SimpleDepartment;
             complex.employees.Add(GetEmployee(simple));
        }
        else if (dep is ComplexDepartment) 
        {
            PopulateEmployees(dep as ComplexDepartment);
        }                
    }            
}

private Employee GetEmployee(SimpleDapartment simple)
{
    var employee = new Employee();
    // some code here

    return employee;
}

【问题讨论】:

  • 当您在else if 分支中递归时,您会将其他员工添加到department 的集合中...
  • 您正在为子复杂部门填充员工。当您从递归调用中返回时,您正在查看父部门,实际上您并没有直接添加任何内容。

标签: c# c#-3.0


【解决方案1】:

让您的代码正常工作(快速而肮脏):

private void PopulateEmployees(ComplexDepartment complex)
{            
    foreach (var dep in complex.Departments)
    {                
        if (dep is SimpleDepartment)
        {
             var simple = dep as SimpleDepartment;
             complex.employees.Add(GetEmployee(simple));
        }
        else if (dep is ComplexDepartment) 
        {
            PopulateEmployees(dep as ComplexDepartment);
            // you need this here, because you collect the additional employees in dep
            complex.employees.AddRange(dep.employees);
        }                
    }            
}

让你的代码工作(更干净):

private void PopulateEmployees(ComplexDepartment complex, ComplexDepartment addTo)
{            
    foreach (var dep in complex.Departments)
    {                
        if (dep is SimpleDepartment)
        {
             var simple = dep as SimpleDepartment;
             addTo.employees.Add(GetEmployee(simple));
        }
        else if (dep is ComplexDepartment) 
        {
            PopulateEmployees(dep as ComplexDepartment, addTo);
        }                
    }            
}

// Call it like
PopulateEmployees(myDep, myDep);

为什么不做无损:

   private IEnumerable<Employee> EnumerateEmployees(ComplexDepartment complexDepartment)
    {            
        foreach (var department in complexDepartment.Departments)
        {                
            if (department is SimpleDepartment)
                yield return GetEmployee((SimpleDepartment) department);
            else if (department is ComplexDepartment) 
            {
                foreach(var e in EnumerateEmployees(department))
                   yield return e;
            }                
        }            
    }

但如果你的结构很深,你可能会遇到 StackOverflows 的问题 - 所以我建议使用累加器或仅使用 LINQ。

代码只是为了演示如何使用递归来实现;)

【讨论】:

  • 一个简单的部门只能有一名员工,因此 GetEmployee 方法只返回一名员工。
  • 是的,抱歉 - 很容易修复;)
  • 谢谢。但是我仍然不明白我在代码中做错了什么,员工集合在递归结束时被清除?
  • 您将员工添加到您迭代的部门 - 我添加了如何解决此问题的部分
  • 啊..我现在明白了。非常感谢!
猜你喜欢
  • 2021-09-20
  • 2011-12-20
  • 2013-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多