CLR via C# 数组 简介

数组是允许多个数据项作为集合来处理的机制。CLR支持一维、多维和交错数组(即数组构成的数组)。所有数组类型都隐式地从System.Array 抽象类派生,后者有派生自System.Object。这意味着数组始终是引用类型,是在托管堆上分配的。

在应用程序的变量或字段中,包含的是对数组的引用,而不是包含数组本身的元素。

第一行代码声明 myInts 变量,它能指向包含 int 值的一维数组。myInts 刚开始被设为 null ,因为当时还没有分配数组。

第二行代码分配了含有100个int 值的数组,所有int 都被初始化为0。

由于数组是引用类型,所以会在托管堆上分配容纳100个未装箱int 所需的内存块。

实际上,除了数组元素,数组对象占据的内存块还包含一个类型对象指针、一个同步块索引和一些额外的成员(这些额外的成员称为 overhead 字段或者说“开销字段”====额外的开销信息 包括数组的秩(即rank,或称数组的维数)、数组每一维的下限(几乎总是0)和每一维的长度,还包含数组的元素类型)。

该数组的内存块地址被返回并保存到 myInts 变量中。

当然还可以创建引用类型的数组:

第一行代码声明 myStrings 变量,它指向包含 string 引用的一维数组。 myStrings 刚开始被设为 null ,因为当时还没有分配数组。

第二行代码分配了含有50个string引用的数组,这些引用全被初始化为null。由于string是引用类型,所以创建数组只是创建了一组引用。

这个内存块的地址被返回并保存到myStrings变量中。

为了符合“公共语言规范”(Common Language Specification,CLS)的要求,所有数组都必须是0基数组(即最小索引为0)。这样就可以用C#的方法创建数组,并将数组的引用传给用其他语言(比如VB)写的代码。此外,由于0基数组是最常用的数组(至少目前是),所以 Microsoft花了很大的力气优化性能。不过,CLR的确支持非0基数组,只是不提倡使用。对于不介意稍许性能下降或者跨语言移植问题的用户可以用。

应尽可能使用一维0即数组,有时也将这种数组称为SZ(SZ是 single-dimension,zero-based(一维0基)的简称)数组或向量(vector)。向量的性能是最佳的,因为可以使用一些特殊的IL指令(比如 newarr,ldelem,ldelema,ldlen和stelem)来处理。

必要时也可以使用多维数组。

CLR还支持交错数组(jagged array),即数组构成的数组。0基一维交错数组的性能和普通向量一样好。不过,访问交错数组的元素意味着必须进行两次或更多次数组访问。

注意  CLR 会验证数组的有效性。换句话说,不能创建含有10个元素的数组(索引编号0~9),然后视图访问索引-5或者10的元素。

这样会导致 System.IndexOutOfRangeException 异常。允许访问数组范围之外的内存会破坏类型安全性,而且会造成潜在的安全漏洞,所以CLR不允许可验证的代码这么做。通常,索引范围检查对性能的影响微乎其微,因为 JIT 编译器只在循环开始之前检查一次数组边界,而不是每次循环迭代都检查。不过,如果仍然担心 CLR索引检查造成的性能损失,可以在C#中使用 unsafe 代码来访问数组。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值