2011-01-06 8 views
27

¿Es posible realizar la recursión con un delegado de Func? Tengo los siguientes, que no se compila porque el nombre de la Func no está en el ámbito ...Recursión con 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

Eso funciona de fábrica en Mono http://www.ienablemuch.com/2010/11/simulate-nested-recursive-function-in-c_08.html –

+0

Este es un duplicado de http://stackoverflow.com/questions/1079164/c-recursive-functions-with-lambdas/1079609#1079609 –

Respuesta

45

De esta manera:

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

Su código produce un error porque eres tratando de usar la variable antes de asignarla.
Su expresión lambda se compila antes de que se establezca la variable (la variable solo se puede establecer en una expresión completa), por lo que no puede usar la variable.
Establecer la variable a null primero evita este problema, porque ya se establecerá cuando se compila la expresión lambda.

Como un enfoque más poderoso, puede usar un YCombinator.

+0

+1 Para el trabajo sobre el tema. Realmente me gustaría que C# fuera lo suficientemente "inteligente" como para trabajar sin esta construcción. (Por otro lado, algunos lenguajes tienen una sintaxis diferente para funciones y enlaces de función recursiva.) –

+0

@pst: ver mi explicación ampliada. – SLaks

+0

¡Esa es una hermosa jugada de manos, funciona a la perfección! – t3rse