System.Array是否对值类型执行装箱操作?
我最近在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类的声明语法中,并且只有通过将数组转换为通用接口类型(显式接口实现)才能访问的接口成员没有参考主题。
这是否意味着拳击不会发生? (并会解释我的表现结果)
如果您使用索引器表示法,则不会使用数组。 例如
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。*系列用于处理存储到强类型的数组类型。 使用泛型时,通常在使用T[]
时附加以下前缀: constrained
或readonly
。 stelem.*
类型通常不检查类型。 例如,使用stelem.i4
比使用更快stelem.any Int32
,除非你使用前缀readonly
的,否则它会强制类型检查。
现在typecheck在valuetype数组上是完全无用的,它们不是协变的!
由于运行时生成从零开始的一维数组(称为SZ_array或向量类型),因此它们本身是已知的。
他们有一系列的il op代码: newarr
, stelem.*
, ldelem.*
, ldlen
等。
List<T>
类型在BCL的Microsoft实现中使用T[]
作为其后备存储。 List<T>
不包含。 无论使用列表还是阵列,您都将数据存储在数组中。
上一篇: Does System.Array perform boxing on value types or not?