C#: Funkcje rekurencyjne z Lambda

Poniżej nie kompiluje się:

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

Lokalna zmienna " fac " może nie być inicjalizacja przed uzyskaniem dostępu

Jak można zrobić funkcję rekurencyjną z lambda?

[Update]

Oto również dwa linki, które uważam za interesujące do przeczytania:

  1. Eric Lippert " dlaczego rekurencyjna lambda powoduje określony błąd przypisania?"
  2. Rekurencja anonimowa w C #
Author: Andreas Grech, 2009-07-03

4 answers

Ten specyficzny styl funkcji nie jest obsługiwany przez C# jako jednolinijkowa deklaracja. Musisz rozdzielić deklarację i definicję na 2 linie

Func<int, int> fac = null;
fac = n => (n <= 1) ? 1 : n * fac(n - 1);
 45
Author: JaredPar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-03 12:37:32

Cóż, gdybyś tylko wpisał " dlaczego rekurencyjna lambda powoduje określony błąd przyporządkowania?"w jakiejś wyszukiwarce znalazłbyś odpowiedź w moim artykule na ten temat.

:-)

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

 15
Author: Eric Lippert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-03 14:28:46

Będziesz musiał najpierw utworzyć fac i przypisać go później (co jest dość niefunkcjonalne, ponieważ zależy to od wielu przypisań) lub użyć tzw. Y-combinators.

Przykład:

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

Ale zauważ, że może to być nieco trudne do odczytania/zrozumienia.

 11
Author: Dario,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-05 18:18:23

Od c# 7.0 w końcu możesz zrobić to w jednej linii używając local function

int fac(int n) => (n <= 1) ? 1 : n * fac(n - 1);
 -1
Author: user1859022,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-31 14:18:39