Бокс и Распаковка

У меня есть небольшое сомнение относительно бокса и распаковки в C#.

int i=1;
System.Int32 j = i;

Приведенный выше код можно назвать боксом?

4 ответа

Решение

Нет, это совсем не бокс. int это просто псевдоним для System.Int32, Этот код эквивалентен:

int i = 1;
int j = i;

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

int i = 1;
object j = i;

Или же:

int i = 1;
IComparable j = i;

Просто чтобы немного расширить ответ Джона, бокс также будет происходить, когда вы вызываете не переопределенные или не виртуальные методы базового класса, например,

i.GetType(); //boxing occur here

или пройти int к методу, который требует ссылочный тип

void Foo(object obj) {}

Foo(i); //boxing, no overload takes an int

В первом примере IL вы можете ясно видеть box инструкция

int i = 5;
i.GetType();

IL_0000:  ldc.i4.5    
IL_0001:  stloc.0     // i
IL_0002:  ldloc.0     // i
IL_0003:  box         System.Int32    //<---- boxing
IL_0008:  call        System.Object.GetType

Если вы не переопределите виртуальные методы в ваших типах значений, они также будут упакованы при вызове их

enum MyEnum {}

var e = new MyEnum();
e.ToString(); //box will occur here, see IL for details

IL_0000:  ldc.i4.0    
IL_0001:  stloc.0     // e
IL_0002:  ldloc.0     // e
IL_0003:  box         UserQuery.MyEnum
IL_0008:  callvirt    System.Object.ToString

Те же ситуации со структурами, за исключением того, что они будут использовать callvirt код операции, который будет упаковывать структуру, если это необходимо,

№ int является типом значения.

Упаковка происходит, когда вы назначаете тип значения для объекта.

Это не бокс.

int это псевдоним для System.Int32, Таким образом, ваш код эквивалентен;

int i = 1;
int j = i;

Для бокса должно быть преобразование в объект или интерфейс. Подобно;

int i = 1;
object j = i;

Значение типа класса может быть преобразовано в объект типа или в интерфейсный тип, который реализуется классом, просто обрабатывая ссылку как другой тип во время компиляции. Аналогично, значение типа объекта или значение типа интерфейса может быть преобразовано обратно в тип класса без изменения ссылки (но, конечно, в этом случае требуется проверка типа во время выполнения).

  • Boxing and Unboxing (C# Programming Guide)
  • Boxing and unboxing
Другие вопросы по тегам