C # Обнуляемый тип значения генерирует мусор? - PullRequest
2 голосов
/ 20 августа 2011

Создает ли тип значения Nullable мусор? Например: структура создается не в куче, а в стеке, потому что это тип значения. Но когда эта структура становится обнуляемой, она все еще является типом значения и все еще создается в стеке?

Я задаю этот вопрос, потому что мне нужна структура, допускающая обнуление, которая не генерирует мусор.

Ответы [ 4 ]

20 голосов
/ 20 августа 2011

Структура создается не в куче, а в стеке, потому что это тип значения.

Это распространенное заблуждение, и оно полностью вводит в заблуждение. Структура, которая является элементом массива, создается в куче. Структура, которая является полем класса, создается в куче. Структура, которая является закрытой внешней переменной лямбды, создается в куче. Структуры создаются в куче все время. Структуры создаются в стеке только тогда, когда известно, что их переменные времена жизни короче, чем у метода, в котором они находятся. Очевидно, что они не могут быть созданы в стеке, если их времена жизни длиннее, чем у стека метода !.

Кроме того, все забывают регистры. Регистры не являются ни кучей, ни стеком. Ничто не мешает оптимизатору сгенерировать структуру как регистр, если оптимизатор решит, что запись в регистр стоит.

Но когда эта структура становится обнуляемой, это все еще тип значения?

Да. Обнуляемый тип - это тип значения. (Хотя он не соответствует ограничению типа значения универсального типа или метода и обладает специальным поведением бокса.)

Это все еще создано в стеке?

Если в куче был создан тип значения, не допускающий значения NULL, то и там будет создан тип NULL.

Мне нужна пустая структура, которая не генерирует мусор.

Если ненулевая структура не генерирует мусор, то и очищаемая структура тоже не будет.

3 голосов
/ 20 августа 2011

Не правда, что структуры создаются только в стеке.

В этом посте объясняется, как работает Nullable. Где в памяти хранятся обнуляемые типы?

3 голосов
/ 20 августа 2011

Глядя на Nullable из T в MSDN, становится ясно, что обнуляемые все еще являются структурами и, следовательно, по-прежнему создаются в стеке, где это необходимо.

2 голосов
/ 20 августа 2011

Краткий и точный ответ: если вы хотите, чтобы они не жили в куче, сделайте them :

локальными или временными переменными и локальными переменнымине являются закрытыми внешними переменными анонимного метода или лямбды, и локальные переменные не находятся в блоке итератора.

Довольно рискованно основывать некоторую часть вашей логики на этом фактеподлежит изменению и не несет никаких гарантий.Это относится и к необработанным типам значений, поэтому значения дозорного вместо использования Nullable<T> не устранят эту проблему внезапно.

...