zoukankan      html  css  js  c++  java
  • 【C#进阶系列】16 数组

    首先提一下,个人在项目中已经很少用到数组了,更多的时候使用List<>。

    数组大小固定,如果只是用来存放数据,专门用来读取,更改当然方便。但是更多的时候我们需要进行增删改,这个时候用List<>反而更好。

    所有数组类型都从System.Array抽象类隐式派生,后者又派生自System.Object。

    一个数组的诞生

    String[] arr=String[10];

    当执行上述语句时,CLR会自动为AppDomain创建一个String[]类型。该类型隐式派生自System.Array,所以它可以用System.Array中定义的方法。

    而所有的数组都隐式实现IEnumerable,ICollection和IList,因为System.Array也实现这三个接口。

    并且当创建的是一维0基数组类型,CLR会自动使数组类型实现当前IEnumerable,ICollection和IList这三个接口的基于基础类型及其基类(这里的基础类型就是指String和它的基类Object)的泛型玩法,

    即IEnumerable<String>,ICollection<String>和IList<String>,IEnumerable<Object>,ICollection<Object>和IList<Object>.(而System.Array是不实现的,因为涉及到多维数组和非0基数组)。这里说的0基数组是指数组索引以0开始开始的数组。

    然而如果数组的基础类型是值类型,即int[]这种,是不会实现泛型接口的,只会实现那三个非泛型接口。

    数组始终是引用类型,所以会在堆上分配,而不是像c一样在栈上分配。

    创建引用类型数组,实际上创建的只是一个装满了引用的数组,而具体引用类型并没有被创建,这些引用默认为null。 

    三种数组

    通常来讲我们会用到以下三种数组:

    int[] 一维数组 = new int[5];
    int[,] 多维数组 = new int[3, 4];
    int[][] 交错数组 = new int[2][];
    交错数组[0] = new int[10];
    交错数组[1] = new int[100];

    数组的类型转换

    数组的也可以转换基础类型,比如将String[]类型就可以转换为Object[]类型。

    但是转型要求数组维数相同,且CLR不允许将值类型的数组转化为任何类型。(但是可以用Array.Copy来实现值类型数组的转换)

    如果只是需要将一个数组中的某些元素复制到另一个同类型数组中,那么可以考虑System.Buffer的BlockCopy方法,一看这些奇怪的名字就知道是底层操作,它比Array.Copy快。但是它不能像Array.Copy那样提供转型能力,比如将Object[]转成Int[].

    数组的传递和返回

    数组作为参数来传递,实际上传递的只是数组的引用。

    如果定义了返回数组引用的方法,而且数组中不包含元素,那么就可以返回null,但是推荐返回new int[0]这样的东西。

    创建非0基数组

    老实说本来不打算写的,确实搞不清楚哪里要用到这种东西,如果用来增加代码阅读难度,为了装B强行写垃圾代码倒是个不错的选择。

    Array.CreateInstance这个方法即可,不过这个方法感觉用来动态地创建数组不错。其实知道就行了,一般也用不到,List<>简单方便多了。

    有下限的数组和下限未知的数组

    CLR支持两类数组,一类是一维0基数组,一类是下限未知的一维数组和多维数组

    一般看数组的类型,比如0基数组的类型就是System.String[],非0基数组的类型为System.String[*].

    访问一维0基数组的元素比非0基或多维数组的元素稍快。因为有一些特殊IL指令处理一维0基数组,会导致JIT编译器生成优化代码。

    所以其实交错数组实际上是多个一维数组,也比多维数组的处理更快,所以也可以用交错数组去替代多维数组去提高性能。

    PS:

    《CLR via C#》这章还介绍了如何去用不安全的方式去操作数组:

    可以将数组不作为引用对象而是直接嵌入结构内部,

    也可以用stackalloc语句去在线程栈上分配数组,而不是像之前一样在堆上分配数组。

    然而这种方式一般也就知道就好,主要用来和非托管代码进行互操作。

    因为是用unsafe方式啊,反正不到逼不得已我连想都不会想起来,麻烦,也不安全。

  • 相关阅读:
    SD卡 家族的发展
    onenand小结 及 与nor 和nand 的区别
    PHP程序开发范例学习之表单――获取文本框的值
    Smarty 模板初体验
    symfony object route class: sfDoctrineRoute
    数据结构&算法(PHP描述) 简单选择排序 simple selection sort
    FLEAPHP操作两个数据库
    让Nginx支持ThinkPHP的URL重写和PATHINFO
    Apache中限制和允许特定IP访问(转载)
    php记录日志
  • 原文地址:https://www.cnblogs.com/vvjiang/p/5317788.html
Copyright © 2011-2022 走看看