如果使用索引器表示法,则不使用数组不会装箱。
例如
new int[2];
x=[1]=3;
编译为以下 IL(请注意,行号不相关,因为它们来自其他代码片段)
IL_0011: ldc.i4.2
IL_0012: newarr System.Int32
IL_0017: stfld Int32[] x
IL_001c: ldarg.0
IL_001d: ldfld Int32[] x
IL_0022: ldc.i4.1
IL_0023: ldc.i4.3
IL_0024: stelem.i4
对于无法使用索引器的语言(我真的不知道它们是否存在),在编译时为数组创建了另外两种方法。
它创建了这些公共方法:
public int Get(int index)
public void Set(int index,int value)
这些方法也不会装箱,并且通常无法通过 C# 访问。 (不要问我为什么它们是公共方法)。您可以使用 IL 或通过创建它们的委托来执行它们。它们速度较慢,因为您被迫执行 callvirt 来调用这些方法。
stelem.* 和 ldelem.* 系列用于处理强类型数组类型的存储。使用泛型时通常会附加以下前缀constrained
or readonly
当使用一个T[]
. stelem.*
type 通常不检查类型。例如。使用stelem.i4
比使用更快stelem.any Int32
除非你在它前面加前缀readonly
因为否则它会强制进行类型检查。
现在,类型检查对值类型数组完全没用,因为它们不是协变的!
因为运行时生成从零开始的一维数组(称为 SZ_array 或向量类型)类型,所以它们本身是已知的。
它们有一系列 il 操作码:newarr
,stelem.*
,ldelem.*
,ldlen
etc.
The List<T>
类型使用T[]
其在 BCL 的 Microsoft 实现中的后备存储。List<T>
不装箱。无论使用列表还是数组,您都将数据存储在数组中。