C# System.Array是否对值类型执行装箱?

C# System.Array是否对值类型执行装箱?,c#,arrays,boxing,C#,Arrays,Boxing,我最近对一系列小型结构的列表与[]进行了一些粗略的性能测量。系统。阵列似乎轻而易举地赢得了比赛,所以我同意了 我才刚刚意识到System.Array包含对象类型,所以用结构填充它肯定会导致装箱 然而,缔约国: 在.NET Framework 2.0版中,Array类实现 System.Collections.Generic.IList, System.Collections.Generic.ICollection,以及 System.Collections.Generic.IEnumerable

我最近对一系列小型结构的
列表
[]
进行了一些粗略的性能测量。系统。阵列似乎轻而易举地赢得了比赛,所以我同意了

我才刚刚意识到System.Array包含对象类型,所以用结构填充它肯定会导致装箱

然而,缔约国:

在.NET Framework 2.0版中,Array类实现
System.Collections.Generic.IList
System.Collections.Generic.ICollection
,以及
System.Collections.Generic.IEnumerable
Generic接口。这个 实现在运行时提供给阵列,因此 文档生成工具不可见。因此,通用 接口不会出现在数组的声明语法中 类,并且没有接口成员的引用主题 只能通过将数组强制转换为泛型接口类型来访问 (显式接口实现)


这是否意味着拳击终究不会发生?(并解释我的性能结果)

如果使用索引器表示法,则不使用数组。 e、 g

编译为以下IL(注意行号是不相关的,因为它们来自其他代码片段)

对于不能使用索引器的语言(我真的不知道它们是否存在),在编译时会为数组创建另外两个方法

它创建以下公共方法:

public int Get(int index)
public void Set(int index,int value)
这些方法也不装箱,通常无法通过C#访问。(不要问我为什么它们是公共方法)。您可以使用IL或通过为它们创建委托来执行它们。它们的速度较慢,因为您必须执行callvirt来调用这些方法

stelem.*和ldelem.*家族用于处理强类型数组类型的存储。使用泛型时,通常会附加以下前缀
constrated
readonly
使用
T[]
<代码>stelem.*类型通常不检查类型。例如,使用
stelem.i4
比使用
stelem.any Int32
要快,除非您在其前面加上
readonly
,否则会强制进行类型检查

现在,如果valuetype数组不是协变的,那么类型检查在valuetype数组上是完全无用的

因为运行时生成从零开始的一维数组(称为SZ_数组或向量类型),所以它们本机已知

它们有一系列il操作码:
newarr
stelem.
ldelem.
ldlen


列表
类型在BCL的microsoft实现中使用一个
T[]
作为其备份存储<代码>列表不在框中。无论使用列表还是数组,您都在数组中存储内容

为了解释您的性能结果,我们可能应该看看您用来衡量性能的代码。下面是关于数组的堆/堆栈分配及其包含值的另一个答案的补充链接:因为数组是引用类型,所以未绑定的int也存储在托管堆中-没有什么值得考虑的。
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)