Вопрос

Ниже не компилируется:

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

Локальная переменная «FAC» может не быть инициализировано перед доступом

Как создать рекурсивную функцию с лямбда-выражениями?

[Обновлять]

Вот также две ссылки, которые мне было интересно прочитать:

  1. Эрик Липперт «Почему рекурсивная лямбда-выражение вызывает определенную ошибку присваивания?»
  2. Анонимная рекурсия в C#
Это было полезно?

Решение

Этот конкретный стиль функции не поддерживается C# в виде однострочного объявления.Вам необходимо разделить объявление и определение на две строки.

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

Другие советы

Ну, черт возьми, если вы только что напечатали: «Почему рекурсивная лямбда вызывает определенную ошибку назначения?» В некоторую поисковую систему вы бы нашли ответ в моей статье на эту тему.

:-)

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

Вам придется создать 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));            
}

Но учтите, что это может быть сложно читать/понимать.

начиная с C# 7.0 вы, наконец, может сделайте это в одной строке, используя локальная функция

int fac(int n) => (n <= 1) ? 1 : n * fac(n - 1);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top