2011-01-06 19 views
27

Funcデリゲートで再帰を行うことはできますか?私はの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. 
    } 
}; 
+0

これはMonoですぐに使用できますhttp://www.ienablemuch.com/2010/11/simulate-nested-recursive-function-in-c_08.html –

+0

これはhttp: /stackoverflow.com/questions/1079164/c-recursive-functions-with-lambdas/1079609#1079609 –

答えて

45

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

あなたがしているので、あなたのコードは、エラーを生成します変数を割り当てる前に変数を使用しようとしています。
ラムダ式は、変数が設定される前にコンパイルされます(変数は完全な式にのみ設定できます)。そのため、変数は使用できません。
変数をnullに設定すると、ラムダ式のコンパイル時に既に設定されているため、この問題はまず回避されます。

さらに強力なアプローチとして、YCombinatorを使用できます。

+0

+1仕事のために。私は本当にC#が "スマート"なので、この構造がなくてもうまくいきたいと思っています。 (一方で、いくつかの言語は、関数と再帰関数バインディングの構文が異なります。) –

+0

@pst:私の拡張された説明を参照してください。 – SLaks

+0

それは手のひらの美しさです、完璧に動作します! – t3rse