Box и UnBox, что это значит?

Возможные дубликаты:
Зачем нам нужен бокс и распаковка на С#?


Что такое бокс и распаковка и какие компромиссы?

В С# то, что означает сидение, означает: "Box и UnBox"?

Здесь выдержка из MSDN, где я основал текст.

Но это удобство стоит дорого. Любой тип ссылки или значения, который добавлено в ArrayList, неявно upcast для Object. Если элементы типы значений, они должны быть в коробке, когда они добавляются в список и unboxed при их восстановлении. И то и другое кастинг и бокс и уменьшение количества операций распаковки представление; эффект бокса и unboxing может быть очень значительным в сценарии, в которых необходимо перебрать большие коллекции.

Спасибо!

Ответ 1

Вот более подробное объяснение, в котором рассматривается внутренняя среда выполнения Common Language Runtime.

Сначала давайте сделаем разницу между типами значений и ссылочными типами:

  • Тип значения хранится в стек, а его копия передается вызываемым методам
  • Контрольное значение сохраняется в управляемой куче, и стек содержит только указатель (ссылку) на его местоположение. Местоположение, а не объект, передается вызываемым методам.

Если вы не знаете, что такое стек (не обижайтесь), это область памяти, которая содержит локальные переменные в методе и адресах функций вызывающего абонента, используемых для инструкции return (просто для краткости и обеспечения общий ответ). При вызове метода достаточная область в стеке выделяется статически, поэтому распределение стека всегда называется статическим распределением.

Вместо этого куча представляет собой область памяти, отделенную от стека, свойство выполняющегося процесса, в котором распределение должно быть сначала потребовано операционной системе, и почему оно называется динамическое размещение ( если вы не работаете в инструкции if, например, память может не выделяться для вашего процесса, а стек всегда выделяется).

Просто, чтобы сделать окончательный пример для кучи и стека: на языках, таких как С++, объявление int[100] a; статически выделяет 100 * 8 байтов в стеке (предполагается 64-разрядная система), а int* a = new int[100]; объявляет 8 байтов ( на 64-битных системах) в стеке И запросит еще 800 байтов в куче, если и где доступно.

Теперь поговорим о С#:

Бокс

Поскольку int является типом значения и выделяется в стеке, когда вы передаете его объекту или любому другому ссылочному типу (на самом деле нет другого ссылочного типа, из которого int может наследовать, но это общее правило) значение должен обязательно стать ссылочным типом. Таким образом, выделяется новая область в куче, объект помещается внутри нее, и стек содержит указатель на нее.

Распаковка

Как раз наоборот: когда у вас есть ссылочный тип, например объект, и хотите передать его типу значения, например int, новое значение должно быть сохранено в стеке, поэтому CLR переходит в кучу, un - загружает значение и копирует его в стек.

Другими словами

Помните примеры int[] и int*? Просто, когда у вас есть int в С#, среда выполнения ожидает, что ее местоположение стека будет удерживать значение, но вместо этого, когда у вас есть object, он ожидает, что его реальное значение будет находиться в месте кучи, на которое указывает стек.

Ответ 2

В .net Framework есть два разных типа.

типы значений такие как int, double, single

ReferenceTypes ArrayList  Список  и многие, многие другие

Переменные типа ValueTypes хранятся в Stack ReferenceTyped переменные хранятся в куче

Переменные типа ValueTypes сохраняют значение VALUE Переменные ReferenceTyped сохраняют значение ССЫЛКИ значением

поэтому, если вы скопируете переменную ValueType - существует реальная копия значения но если вы скопируете переменную ReferenceType - вы получите дополнительную ссылку к переменной SAME.

Бокс в вашем вопросе означает, что переменная valueType Variable (например, int) будет обрабатываться как ссылочная Type Variable -.net, которая передает ее в новый блок. Таким образом, он будет инкапсулирован в кучу, и в нем будут ссылки (ссылки).

Если вы хотите, чтобы значение снова находилось в переменной ValueType, вам нужно распаковать его (выведите его из коробки). Таким образом, значение будет выведено из кучи - и сохранено/передано в стек еще раз.

Ответ 3

ArrayList хранит только объекты. Для ссылочного типа (например, String) это не проблема, но для ValueType (int, DateTime,..) это.

Эти значения параметров необходимо преобразовать в объект, прежде чем вы сможете сохранить их как обычный объект. Это "преобразование в объект" называется "бокс" и занимает немного времени.

Когда вы читаете значение обратно, вам нужно преобразовать из Object в int (или что-то еще). Это называется "распаковкой".