Термин «бокс» очень непрозрачен, но с помощью отладчика легко визуализировать происходящее. Напишите небольшое приложение в консольном режиме, например:
using System;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
int value = 42;
object obj = value;
} // <== Breakpoint here
}
}
Установите точку останова там, где это указано, и нажмите F5. При достижении точки останова используйте «Отладка + Windows + Память + Память» 1. В поле «Адрес» введите «obj». Вы получите шестнадцатеричный дамп содержимого памяти объекта. Щелкните правой кнопкой мыши окно и выберите «4-байтовое целое число», лучший способ визуализации объекта в этом случае. Вы увидите нечто похожее на это:
0x01CBF6BC 6e1a2d34 0000002a
Интересными частями здесь являются 0x01CBF6BC, это адрес объекта в куче мусора. Следующее шестнадцатеричное число, 6e1a2d34, представляет собой так называемый «дескриптор типа», также известный как «указатель таблицы методов». Это «cookie», который идентифицирует тип объекта. System.Int32 в этом случае. Очень важно, что он будет использован позже, когда объект будет распакован обратно в Int32, чтобы убедиться, что значение в штучной упаковке является целым числом.
Следующее значение, которое вы видите, 0000002a, это значение в штучной упаковке. Вы можете использовать калькулятор Windows в режиме программирования, чтобы преобразовать обратно в десятичное число, это 42.
Поэкспериментируйте с этим, используя разные значения и разные типы, чтобы увидеть, как это влияет на упакованный объект. Вы можете изменить гекс и посмотреть, как он влияет на значение obj, отображаемое отладчиком.
Шестнадцатеричный дамп, который я вам дал, был для 4-байтового коробочного значения, для двойного бокса потребуется 8 байт. Упаковка структуры займет больше байтов. Также есть часть заголовка объекта, которую вы не можете видеть, так называемый syncblock, расположенный по адресу - 4. Попробуйте оператор блокировки, чтобы увидеть это изменение.