Если я присваиваю простой тип значения (например, int) атрибуту типа ValueType, это значение затем помещается в коробку?
Например, если я это сделаю:
int i = 4;
ValueType test = i;
Будет ли введено значение?
Да, будет. Это связано с тем, что каждый тип занимает постоянный объем памяти во время выполнения (int
занимает, например, 4 байта). Структура будет занимать столько места, сколько требуется для размещения всех полей в памяти.
Поскольку вы можете сохранить любой тип значения в ValueType
, а так как ValueType
должен быть точно того же размера, что и тип, который вы назначаете test
, тип ValueType
на самом деле является ссылочным типом.
Рассмотрим:
int a = 0;
long b = 1;
ValueType test;
test = a;
test = b;
Это абсолютно правильный код. test
должен занимать фиксированный размер в стеке, а a
и b
- разные размеры. Надеюсь, это объясняет, почему именно ValueType
не может быть типом значения. (Это связано с тем, почему вы не можете выводить типы значений.)
Да, это будет в коробке - ValueType
является ссылочным типом (классом), достаточно запутанным:) Это просто тип от который каждый тип значения "наследует" (непосредственно в случае структур и косвенно в случае перечислений).
Бокс происходит в любое время, когда вы присваиваете значение типа значения переменной ссылочного типа, включая object
, ValueType
, Enum
и любые интерфейсы. (Это также происходит при использовании значения типа значения в качестве аргумента, где параметр является одним из этих типов и т.д.)
ValueType
является ссылочным типом. IL, сгенерированный в этом назначении, фактически блокирует структуру.
Вот пример командной строки при назначении объекту:
void Main()
{
object o = 1;
Console.Write(o);
}
IL_0000: ldc.i4.1
IL_0001: box System.Int32
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: call System.Console.Write
И при назначении ValueType
:
void Main()
{
ValueType o = 1;
Console.Write(o);
}
IL_0000: ldc.i4.1
IL_0001: box System.Int32
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: call System.Console.Write
ValueType
является ссылочным типом.