【问题标题】:Recursion with Func使用 Func 进行递归
【发布时间】:2011-06-04 10:28:28
【问题描述】:

是否可以使用 Func 委托进行递归?我有以下内容,因为 Func 的名称不在范围内,所以无法编译...

Func<long, long, List<long>, IEnumerable<long>> GeneratePrimesRecursively = (number, upperBound, primeFactors) => 
{
    if (upperBound < number)
    {
        return primeFactors;
    }
    else
    {
        if (!primeFactors.Any(factor => number % factor == 0)) primeFactors.Add(number);
        return GeneratePrimesRecursively(++number, upperBound, primeFactors); // breaks here.
    }
};

【问题讨论】:

标签: c# recursion primes


【解决方案1】:

像这样:

Func<...> method = null;
method = (...) => {
    return method();
};

您的代码会产生错误,因为您在分配变量之前尝试使用它。
您的 lambda 表达式是在设置变量之前编译的(变量只能设置为完整的表达式),因此它不能使用该变量。
首先将变量设置为null 可以避免这个问题,因为它会在编译 lambda 表达式时设置。

作为一种更强大的方法,您可以使用YCombinator

【讨论】:

  • +1 用于工作。我真的希望 C# 足够“聪明”,可以在没有这个结构的情况下工作。 (另一方面,某些语言对函数和递归函数绑定有不同的语法。)
  • @pst:见我的扩展解释。
  • @Slaks 是的,是的——但这种情况可能是 C# 规范的一部分(使 lambda 的范围包括它们所在的声明语句,如果有的话) - 在这种情况下,它将是完全合法的并被接受。现在只是一厢情愿。
  • @pst:不,它不能。 lambda 表达式与变量无关。
  • @SLaks, @pst:pst 在这里有正确的想法,但细节并不完全正确。这可能合法的原因是因为我们可以推断在编译时变量“method”不能被执行lambda主体读取,直到它被写入之后。我们可以知道这一点,因为静态分析可以显示初始化不会调用 lambda。本质上,我们需要做的是告诉编译器,获取匿名方法引用的委托构造函数不会调用它。因此,我们可以抑制明确的分配错误。
猜你喜欢
  • 2018-11-02
  • 2015-02-02
  • 2012-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多