28

以下不编译:

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

局部变量“fac”在访问之前可能未初始化

你怎么能用 lambdas 做一个递归函数?

[更新]

这里还有两个我觉得有趣的链接:

  1. Eric Lippert 的“为什么递归 lambda 会导致明确的赋值错误?”
  2. C#中的匿名递归
4

3 回答 3

49

C# 不支持这种特殊风格的函数作为单行声明。您必须将声明和定义分成两行

Func<int, int> fac = null;
fac = n => (n <= 1) ? 1 : n * fac(n - 1);
于 2009-07-03T12:37:32.330 回答
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));            
}

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

于 2009-07-03T12:41:59.327 回答
-2

从 c# 7.0 开始,您终于可以使用本地函数在一行中完成此操作

int fac(int n) => (n <= 1) ? 1 : n * fac(n - 1);
于 2018-01-31T14:18:39.587 回答