Лямбда в C #, Захват внешних переменных - Pls объясните пример из книги «C # в словах 5.0»

1

Какая разница между

static Func<int> Natural()
{
  int seed = 0;
  return () => seed++;      // Returns a closure
}

а также

static Func<int> Natural()
{
  return() => { int seed = 0; return seed++; };
}

Зачем

static void Main()
{
  Func<int> natural = Natural();
  Console.WriteLine (natural());       
  Console.WriteLine (natural());         
}

показывает 0 1 для первого Natural() и 0 0 для второго? Благодарю!

Теги:
lambda

2 ответа

11
Лучший ответ

Разница в том, что в первой версии вы объявляете переменную, а затем фиксируете переменную в выражении лямбда. Сама переменная "выживает" по нескольким вызовам делегата.

Во втором примере вы объявляете переменную внутри выражения лямбда, поэтому каждый раз, когда выполняется делегирование, переменная эффективно запускается снова.

Другими словами, это разница между:

class NaturalImpl
{
    public int seed;

    public int Method()
    {
        return seed++;
    }
}

Func<int> natural = new NaturalImpl().Method;

а также:

class NaturalImpl
{
    public int Method()
    {
        int seed = 0;
        return seed++;
    }
}

Func<int> natural = new NaturalImpl().Method;

Обратите внимание на разницу между переменной экземпляра в первой версии и локальной переменной во второй.

(Это не совсем то, как будет выглядеть реализация второй формы: это будет статический метод в охватывающем классе, поскольку он без гражданства, но...)

  • 0
    Извините за откат этого, я сомневался в себе на секунду (ранее я одобрил предложенную редакцию).
3

В первом случае всякий раз, когда называется Natural она возвращает функцию, которая ссылается на одну и ту же переменную seed каждый раз (тот, который определен внутри самого Natural).

Во втором случае он возвращает функцию, которая ссылается на другую переменную seed каждый раз (ту, которая определена внутри тела указанной функции).

Разумеется, в первом случае каждая возвращенная функция сможет "видеть" изменения в seed сделанные другими, потому что все они работают с одним и тем же значением.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню