拳击和拆箱会在阵列中发生吗?

Ais*_*shu 13 c# arrays boxing

我是编程的新手,

根据MSDN,

Boxing是将值类型转换为类型对象或由此值类型实现的任何接口类型的过程.当CLR选中一个值类型时,它将值包装在System.Object中并将其存储在托管堆上.取消装箱从对象中提取值类型.拳击是隐含的; 拆箱是明确的.

我知道我们可以在arraylist中存储任何对象,因为它system.object是所有类型的基础.拳击和拆箱发生在阵列列表中.我同意这一点.

拳击和拆箱会发生在阵列中吗?因为我们可以创建如下的对象数组

object[] arr = new object[4] { 1, "abc", 'c', 12.25 };
Run Code Online (Sandbox Code Playgroud)

我的理解是拳击和拆箱发生在这样的数组正确吗?

Yuv*_*kov 12

拳击和拆箱会发生在阵列中吗?

数组本身已经是一个引用类型,数组本身没有装箱.但是,由于您的某些元素是值类型(int,doublechar),并且您的数组类型是object,因此将对所述元素进行装箱.当您想要提取它时,您需要将其解包:

var num = (int)arr[0];
Run Code Online (Sandbox Code Playgroud)

您可以在生成的IL中看到它:

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
Run Code Online (Sandbox Code Playgroud)


Ale*_*kov 6

是的,当放入数组中时,值类型元素(1,'c'和12.25)将被装箱object[].

字符串"abc"将按原样放置,因为它是引用类型对象.


cho*_*mba 5

每次将值类型的值赋给类型的变量时,object都会发生装箱操作,所以当你这样做时:

object[] arr = new object[4] { 1, "abc", 'c', 12.25 };
Run Code Online (Sandbox Code Playgroud)

这相当于

object[] arr = new object[4];
arr[0] = 1;
arr[1] = "abc";
arr[2] = 'c';
arr[3] = 12.25
Run Code Online (Sandbox Code Playgroud)

三盒将被创建,用于存储1,12.25"C",因为他们是值类型的值.