Какая разница между
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 для второго? Благодарю!
Разница в том, что в первой версии вы объявляете переменную, а затем фиксируете переменную в выражении лямбда. Сама переменная "выживает" по нескольким вызовам делегата.
Во втором примере вы объявляете переменную внутри выражения лямбда, поэтому каждый раз, когда выполняется делегирование, переменная эффективно запускается снова.
Другими словами, это разница между:
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;
Обратите внимание на разницу между переменной экземпляра в первой версии и локальной переменной во второй.
(Это не совсем то, как будет выглядеть реализация второй формы: это будет статический метод в охватывающем классе, поскольку он без гражданства, но...)
В первом случае всякий раз, когда называется Natural
она возвращает функцию, которая ссылается на одну и ту же переменную seed
каждый раз (тот, который определен внутри самого Natural
).
Во втором случае он возвращает функцию, которая ссылается на другую переменную seed
каждый раз (ту, которая определена внутри тела указанной функции).
Разумеется, в первом случае каждая возвращенная функция сможет "видеть" изменения в seed
сделанные другими, потому что все они работают с одним и тем же значением.