28

以下はコンパイルされません。

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

アクセスする前にローカル変数「fac」が初期化されていない可能性があります

ラムダを使用して再帰関数を作成するにはどうすればよいですか?

[アップデート]

また、読んでいて興味深いと思った 2 つのリンクを次に示します。

  1. Eric Lippert の「なぜ再帰的ラムダが明確な代入エラーを引き起こすのか?」
  2. C# での匿名再帰
4

3 に答える 3

49

この特定のスタイルの関数は、C#では1行の宣言としてサポートされていません。宣言と定義を2行に分ける必要があります

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 以降では、最終的にローカル関数を使用して 1 行でこれを行うことができます

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