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

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

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

一个数组的诞生

  1. String[] arr=String[];

当执行上述语句时,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。

三种数组

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

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

数组的类型转换

数组的也可以转换基础类型,比如将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方式啊,反正不到逼不得已我连想都不会想起来,麻烦,也不安全。

【C#进阶系列】16 数组的更多相关文章

  1. JavaScript进阶系列02,函数作为参数以及在数组中的应用

    有时候,把函数作为参数可以让代码更简洁. var calculator = { calculate: function(x, y, fn) { return fn(x, y); } }; var su ...

  2. C#进阶系列 ---- 《CLR via C#》

      [C#进阶系列]30 学习总结 [C#进阶系列]29 混合线程同步构造 [C#进阶系列]28 基元线程同步构造 [C#进阶系列]27 I/O限制的异步操作 [C#进阶系列]26 计算限制的异步操作 ...

  3. C#进阶系列——WebApi 接口参数不再困惑:传参详解

    前言:还记得刚使用WebApi那会儿,被它的传参机制折腾了好久,查阅了半天资料.如今,使用WebApi也有段时间了,今天就记录下API接口传参的一些方式方法,算是一个笔记,也希望能帮初学者少走弯路.本 ...

  4. 【转】C#进阶系列——WebApi 接口参数不再困惑:传参详解

    原文地址:http://www.cnblogs.com/landeanfen/archive/2016/04/06/5337072.html 阅读目录 一.get请求 1.基础类型参数 2.实体作为参 ...

  5. Wireshark入门与进阶系列(一)

    摘自http://blog.csdn.net/howeverpf/article/details/40687049 Wireshark入门与进阶系列(一) “君子生非异也,善假于物也”---荀子 本文 ...

  6. Wireshark入门与进阶系列(二)

    摘自http://blog.csdn.net/howeverpf/article/details/40743705 Wireshark入门与进阶系列(二) “君子生非异也,善假于物也”---荀子 本文 ...

  7. HTML5 进阶系列:indexedDB 数据库

    前言 在 HTML5 的本地存储中,有一种叫 indexedDB 的数据库,该数据库是一种存储在客户端本地的 NoSQL 数据库,它可以存储大量的数据.从上篇:HTML5 进阶系列:web Stora ...

  8. 深入理解javascript函数进阶系列第一篇——高阶函数

    前面的话 前面的函数系列中介绍了函数的基础用法.从本文开始,将介绍javascript函数进阶系列,本文将详细介绍高阶函数 定义 高阶函数(higher-order function)指操作函数的函数 ...

  9. 智能合约语言 Solidity 教程系列5 - 数组介绍

    写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解, 如果你还不了解,建议你先看以太坊是什么 本文前半部分是参考Solidity官方文档(当前最新版本: ...

  10. 超全PHP学习资源整理:入门到进阶系列

    PHP是少数几门在语言层面饱受诟病,但在实际开发和应用上却又让人无法撒手的语言之一.就好比路边摊小吃,一遍骂人家不卫生,一遍却又说:真香.所谓接地气,不外如此,大道理不说,PHP光是轮子多.市场占有率 ...

随机推荐

  1. Ajax跨域访问XML数据的另一种方式——使用YQL查询语句

    XML数据默认是不能在客户端通过Ajax跨域请求读取的,一般的做法是在服务器上写一个简单的代理程序,将远程XML的数据先读到本地服务器,然后客户端再从本地服务器通过Ajax来请求.由于我们不能对数据源 ...

  2. 基于Vue封装分页组件

    使用Vue做双向绑定的时候,可能经常会用到分页功能 接下来我们来封装一个分页组件 先定义样式文件 pagination.css ul, li { margin: 0px; padding: 0px;} ...

  3. 移动端使用localResizeIMG4压缩图片

    移动h5开发避免不了上传图片,一般我们使用html自带的控件input或者使用微信上传API.但微信上传API不是任何地方都可以使用的,使用html自带的控件input上传又免不了图片体积太大,上传不 ...

  4. 搭建LNAMP环境(五)- PHP7源码安装Redis和Redis拓展

    上一篇:搭建LNAMP环境(四)- 源码安装PHP7 一.安装Redis 1.创建redis用户组和用户 groupadd redis useradd -r -g redis -s /sbin/nol ...

  5. replicate复制函数

    按指定次数重复字符表达式 REPLICATE ( character_expression, integer_expression) character_expression 字符数据型的字母数字表达 ...

  6. KendoUI系列:Window

    1.基本使用 <link href="@Url.Content("~/Content/kendo/2014.1.318/kendo.common.min.css") ...

  7. struts2获取web元素(request、session、application)

    一.Action中获取 第一种方式: 通过ActionContext,这种方式取到的对象是Map类型 import java.util.Map; import com.opensymphony.xwo ...

  8. JSP网站开发基础总结《四》

    经过前几篇的摸爬滚打,下面我们就开始我们真正的数据库操作了,本篇重点在于如何在网站端编写数据库操作语句,内容不多,就是我们常见的增删改查. 0.数据库对象创建: 在JAVASE基础知识总结时,就为大家 ...

  9. javase基础复习攻略《八》

    进入第八篇,我们开始讨论JAVA的IO初步.在JAVA程序中,对数据的输入\输出操作以"流"(stream)方式进行,J2SDK提供了各种各样的"流"类,用于获 ...

  10. poj3342Party at Hali-Bula(树形dp)

    /* 树形dp! 判重思路: 当dp[v][0]==dp[v][1]时,很自然,flag[u][0]必然是有两种方案的.flag[u][1]则不然, 因为它只和dp[v][0]有关系.而若flag[v ...