Я чувствую, что у меня довольно приличное понимание закрытий, как их использовать, и когда они могут быть полезны. Но я не понимаю, как они на самом деле работают за кулисами в памяти. Пример кода:
public Action Counter()
{
int count = 0;
Action counter = () =>
{
count++;
};
return counter;
}
Обычно, если {count} не был захвачен закрытием, его жизненный цикл будет привязан к методу Counter(), и после его завершения он исчезнет с остальной частью распределения стека для Counter(). Что происходит, когда оно закрывается? Охватывает ли все распределение стека для этого вызова Counter()? Копирует ли он в кучу? Он никогда не получает выделение в стеке, но распознается компилятором как закрытое и поэтому всегда живет в куче?
В этом конкретном вопросе меня в первую очередь интересует, как это работает в С#, но не будет против сравнения с другими языками, поддерживающими закрытие.