c# - 递归 IEnumerable 没有按预期工作?

标签 c# recursion ienumerable

我写了一个递归函数,它产生 IEnumerable<int>

IEnumerable<int>   Go(int b  )
{
 if (b==0) yield  return 0;
   else
 foreach (var element in Go(b-1))
  {
    yield return element;
  }
}

所以如果我写

foreach (var element in Go(3))
{
    Console.WriteLine (element);
}

它应该产生

0
1
2
3

但它并没有像预期的那样工作。 (它显示 0)。

在正常的递归函数中(返回 int - 没有 Ienumerable)它工作正常。

问题:

如何修复代码以使其产生预期值?

注意。不,没有理由使用递归 Ienumerables。在玩过递归 yield 之后,我才想到这一点。

最佳答案

因为你永远不会 yield b 本身而只会 yield 0。

IEnumerable<int> Go(int b)
{
    if(b > 0) {
         foreach (var element in Go(b-1))
            yield return element;
    }
    yield return b;
}

请注意,如果您希望结果序列从 0 开始并向上移动,您必须yield return b foreach 之后。让我们展开对 Go(3) 的第一个调用:

Go(3):
foreach(var element in Go(2)):
    yield return element;
yield return 3;

因此 3 将是序列中的最后一项(因为所有其他项都在它之前产生)。现在让我们展开 Go(2):

Go(3):
    Go(2):
    foreach(var element in Go(1)):
        yield return element;
    yield return 2;
yield return 3;

开始(1):

Go(3):
    Go(2):
        Go(1):
            foreach(var element in Go(0))
                yield return element;
        yield return 1;
    yield return 2;
yield return 3;

如您所见,结果相对于调用“向后”链接:

Go(3) --> Go(2) --> Go(1) --> Go(0) --> 0 --> 1 --> 2 --> 3

关于c# - 递归 IEnumerable 没有按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29122690/

相关文章:

haskell - 此折叠实现中的错误

.net - 集合论和.NET

c# - 如何(自动)为 MVC + 实体生成 web api Controller 或遗传查询所有类型

c# - 无法异步使用 Ajax.BeginForm() 上传文件

c# - 在 Entity Framework 中完成子实体的插入/更新/删除

c# - IdentityServer4 中 token 端点的无效 HTTP 请求

algorithm - 了解运行时间的递归

algorithm - 最后的算法舞蹈

c# - 您最喜欢的非内置 LINQ to Objects 运算符是什么?

c# - 从集合继承和实现可枚举接口(interface)时,IEnumerable 扩展方法 (System.Linq) 不可用