Позвольте мне извиниться заранее - я, вероятно, собираю терминологию. У меня есть смутное понимание того, что такое закрытие, но не могу объяснить поведение, которое я вижу. По крайней мере, я думаю, что это проблема закрытия. Я искал в Интернете, но не нашел правильных ключевых слов, чтобы получить то, что я хочу.
В частности - у меня есть два блока кода, которые ДЕЙСТВИТЕЛЬНО ПОДОБНЫ (по крайней мере, для моих глаз). Во-первых:
static void Main(string[] args)
{
Action x1 = GetWorker(0);
Action x2 = GetWorker(1);
}
static Action GetWorker(int k)
{
int count = 0;
// Each Action delegate has it own 'captured' count variable
return k == 0 ? (Action)(() => Console.WriteLine("Working 1 - {0}",count++))
: (Action)(() => Console.WriteLine("Working 2 - {0}",count++));
}
Если вы запустите этот код и вызовите x1() и x2(), вы увидите, что они поддерживают отдельное значение "count".
foreach(var i in Enumerable.Range(0,4))
{
x1(); x2();
}
Выходы:
Working 1 - 0
Working 2 - 0
Working 1 - 1
Working 2 - 1
Working 1 - 2
Working 2 - 2
Working 1 - 3
Working 2 - 3
Это имеет смысл для меня и соответствует объяснениям, которые я прочитал. За кулисами создается класс для каждого делегата/действия, а классу присваивается поле для хранения значения "count". Я лег спать, чувствуя себя умным!
НО ТОГДА - я пробовал этот очень похожий код:
// x3 and x4 *share* the same 'captured' count variable
Action x3 = () => Console.WriteLine("Working 3 - {0}", count++);
Action x4 = () => Console.WriteLine("Working 4 - {0}", count++);
И (как говорится в комментарии), здесь совершенно другое поведение. x3() и x4(), похоже, имеют ТОЛЬКО значение счетчика!
Working 3 - 0
Working 4 - 1
Working 3 - 2
Working 4 - 3
Working 3 - 4
Working 4 - 5
Working 3 - 6
Working 4 - 7
Я вижу, что происходит, но я не понимаю, почему с ними обращаются по-разному. В моей голове - мне понравилось это оригинальное поведение, которое я видел, но более поздний пример меня смущает. Я надеюсь, что в этом есть смысл. Благодаря