C#:使用Lambdas的递归函数

时间:2009-07-03 12:34:08

标签: c# recursion lambda factorial

以下内容无法编译:

Func<int, int> fac = n => (n <= 1) ? 1 : n * fac(n - 1);
  

局部变量'fac'可能不是   在访问之前初始化

如何使用lambdas创建递归函数?

[更新]

以下是我发现有趣的两个链接:

  1. Eric Lippert's "Why does a recursive lambda cause a definite assignment error?"
  2. Anonymous Recursion in C#

4 个答案:

答案 0 :(得分:45)

C#不支持这种特殊的函数样式作为单行声明。你必须将声明和定义分成2行

Func<int, int> fac = null;
fac = n => (n <= 1) ? 1 : n * fac(n - 1);

答案 1 :(得分:15)

那么geez,如果你只是输入“为什么递归lambda导致明确的赋值错误?”在一些搜索引擎中,你已经在我关于这个主题的文章中找到了答案。

: - )

http://blogs.msdn.com/ericlippert/archive/2006/08/18/why-does-a-recursive-lambda-cause-a-definite-assignment-error.aspx

答案 2 :(得分:11)

您必须先创建fac并稍后再分配(这非常不起作用,因为它取决于多个分配)或使用所谓的Y-combinators

示例:

delegate Func<TIn, TOut> FixedPointFunction<TIn, TOut>(Func<TIn, TOut> f);

static Func<T, TRes> Fix<T, TRes>(FixedPointFunction<T, TRes> f) {
    return f(x => Fix(f)(x));
}

static void Main(string[] args) {

    var fact = Fix<int, int>(f => x => (x <= 1) ? x : x * f(x - 1));

    Console.WriteLine(fact(5));            
}

但请注意,这可能有点难以阅读/理解。

答案 3 :(得分:-1)

自c#7.0起,您最终可以使用local function

在一行中执行此操作
int fac(int n) => (n <= 1) ? 1 : n * fac(n - 1);