2009-07-03 31 views
27

La continuación no se compila:C#: Las funciones recursivas con Lambdas

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

'fac' variable local puede que no se inicializado antes de acceder

¿Cómo puede hacer una función recursiva con lambdas?

[Actualización]

Aquí hay también dos enlaces que he encontrado interesante leer:

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

¿De verdad quiere? Eso parece una pesadilla para la facilidad de mantenimiento y la comprensión ... – Ian

+0

bueno, tal vez solo un concepto –

Respuesta

45

No se admite Este estilo particular de la función por C# como una declaración de línea única. Hay que separar la declaración y definición en 2 líneas

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

Vas a tener que crear fac primera und asignar más tarde (que es bastante unfunctional porque depende de la asignación múltiple) o utilizar los llamados Y-combinators.

Ejemplo:

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));    
} 

Pero tenga en cuenta que esto podría ser un poco difícil de leer/entender.

15

Bien, si acabaras de escribir "¿por qué un lambda recursivo causa un error de asignación definido?" en algún buscador, hubieras encontrado la respuesta en mi artículo sobre el tema.

:-)

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

+4

Todos los caminos conducen a Lippert: D excelente publicación. –

+3

+1 por 'si acabaras de tipear' ¿por qué un lambda recursivo causa un error de asignación definido? " en algún motor de búsqueda ':-) –

-1

ya que C# 7.0 que finalmente puede hacer esto en una línea usando un local function

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