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

Gaz*_*yer 11 c# arrays boxing

我最近List<>[]一系列小型结构的vs 做了一些粗略的性能测量.System.Array似乎赢得了胜利,所以我顺其自然.

只是在我看来System.Array包含对象类型,所以肯定用结构填充它会导致拳击发生?

但是,System.Array的MSDN条目指出:

在.NET Framework 2.0版,Array类实现 System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T>以及 System.Collections.Generic.IEnumerable<T>通用接口.这些实现在运行时提供给数组,因此文档构建工具不可见.因此,通用接口不会出现在Array类的声明语法中,并且没有可通过将数组转换为通用接口类型(显式接口实现)来访问的接口成员的参考主题.

这是否意味着毕竟不会发生拳击?(并会解释我的表现结果)

Mic*_*l B 12

如果使用索引器表示法,则不使用数组.例如

new int[2];
x=[1]=3;
Run Code Online (Sandbox Code Playgroud)

编译为以下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
Run Code Online (Sandbox Code Playgroud)

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

它创建了这些公共方法::

public int Get(int index)
public void Set(int index,int value)
Run Code Online (Sandbox Code Playgroud)

这些方法既不会封装,也不能通过C#访问.(不要问我为什么他们是公共方法).您可以使用IL或通过创建委托来执行它们.当你被迫做一个callvirt来调用这些方法时,它们会变慢.

stelem.*和ldelem.*系列用于处理存储到强类型数组类型.使用泛型时,通常会附加以下前缀constrainedreadonly使用时T[].stelem.*类型通常不检查类型.例如,使用stelem.i4比使用更快,stelem.any Int32除非您使用前缀,readonly否则它会强制进行类型检查.

现在,对于值类型数组,类型检查完全没用,它们是不协变的!

因为运行时生成从零开始的一维数组(称为SZ_array或矢量类型)类型,所以它们本身是已知的.

还有的为他们的IL操作码家族:newarr,stelem.*,ldelem.*,ldlen等.

List<T>类型T[]在BCL的microsoft实现中使用a 作为其后备存储.List<T>没有盒子.无论使用列表还是数组,都要将数据存储在数组中.