Будут ли бокс и распаковка в Маре?

Я новичок в программировании,

По MSDN,

Бокс - это процесс преобразования типа значения в объект типа или любого типа интерфейса, реализованного этим типом значения. Когда CLR вводит тип значения, он переносит значение внутри объекта System.Object и сохраняет его в управляемой куче. Unboxing извлекает тип значения из объекта. Бокс неявный; unboxing явно.

Я знал, что мы можем хранить любые объекты в arraylist, потому что system.object является базой для всех типов. Бокс и распаковка происходит в списке массивов. Я согласен с этим.

Будет ли бокс и распаковка в массиве? Поскольку мы можем создать массив объектов, как показано ниже

object[] arr = new object[4] { 1, "abc", 'c', 12.25 };

Насколько я понимаю, что бокс и распаковка происходят в таком массиве правильно?

Ответ 1

Будет ли бокс и распаковка в массиве?

Сам массив уже является ссылочным типом, бокса по самому массиву нет. Но, поскольку некоторые из ваших элементов являются типами значений (int, double и char), а ваш тип массива object, для указанного элемента будет бокс. Когда вы захотите извлечь его, вам нужно будет его удалить:

var num = (int)arr[0];

Вы можете увидеть его в сгенерированном ИЛ:

IL_0000: ldarg.0
IL_0001: ldc.i4.4
IL_0002: newarr [mscorlib]System.Object
IL_0007: dup
IL_0008: ldc.i4.0
IL_0009: ldc.i4.1
IL_000a: box [mscorlib]System.Int32 // Boxing of int
IL_000f: stelem.ref
IL_0010: dup
IL_0011: ldc.i4.1
IL_0012: ldstr "abc"
IL_0017: stelem.ref
IL_0018: dup
IL_0019: ldc.i4.2
IL_001a: ldc.i4.s 99
IL_001c: box [mscorlib]System.Char
IL_0021: stelem.ref
IL_0022: dup
IL_0023: ldc.i4.3
IL_0024: ldc.r8 12.25
IL_002d: box [mscorlib]System.Double
IL_0032: stelem.ref
IL_0033: stfld object[] C::arr
IL_0038: ldarg.0
IL_0039: call instance void [mscorlib]System.Object::.ctor()
IL_003e: nop
IL_003f: ret

Ответ 2

Да, элементы типа значения (1, 'c' и 12.25) будут помещены в квадрат при размещении в массиве object[].

Строка "abc" будет помещена как есть, поскольку она является объектом ссылочного типа.

Ответ 3

Каждый раз, когда вы присваиваете значение типа значения переменной типа object, будет выполняться операция бокса, поэтому когда вы делаете:

object[] arr = new object[4] { 1, "abc", 'c', 12.25 };

Что эквивалентно

object[] arr = new object[4];
arr[0] = 1;
arr[1] = "abc";
arr[2] = 'c';
arr[3] = 12.25

Три поля будут созданы для хранения 1, 12.25 и 'c', потому что они являются значениями типов значений.