Ответ 1
Если вы имеете в виду объект (new Foo(i);
), то я понимаю, что нет: это никогда не выделяется в стеке; однако он будет умирать в нулевой генерации, поэтому будет очень эффективно собирать. Я не утверждаю, что знаю каждый темный и прочный угол CLI, но мне не известно ни одного сценария в С#, который приведет к тому, что в стеке будет выделен управляемый ссылочный тип (например, stackalloc
действительно не учитываются и весьма специфичны). Очевидно, что в С++ у вас есть еще несколько параметров, но тогда это не управляемый экземпляр.
Интересно, что в MonoTouch/AOT он может быть собран немедленно, но это не основная виртуальная машина CLI (и для очень специфического сценария).
Что касается переменной - которая обычно находится в стеке (и повторно используется для каждой итерации цикла), но она может быть не. Например, если это "блок-блок итератора", то все не удаленные локальные переменные являются фактически полями на машине-генераторе, созданном компилятором. Чаще всего, если переменная "захвачена" (в анонимный метод или выражение лямбда, оба из которых образуют замыкания), тогда переменная преобразуется в поле в контексте захвата компилятора, и является отдельной для каждой итерации цикла (поскольку foo
объявляется внутри цикла). Это означает, что каждый из них разделен на кучу.
Что касается i
(переменная цикла) - если он захвачен, он становится еще интереснее
- в С# 1.2 захватов не было, но по спецификации переменная цикла является технически пер-итерацией
- в С# 2.0 до 4.0, переменная цикла является общей (вызывает широко известный вопрос об уходе /foreach )
- в С# 5.0 и выше переменная цикла повторяется снова.
это только имеет значение, когда переменная захватывается, но изменяет семантику точно, как она проявляется в контексте capture