这本书讲解 C# 语言十分详细,我将其中的重要内容整理成条款,以备忘。
1. 数组的维度称作秩,每一个维度上有一个长度叫做维度长度,即在某个方向上的位置个数。数组的长度是指所有 维度中元素的总和 。
2. C# 不支持动态数组,数组一旦创建,大小就固定了 。矩形数组是某个维度的所有子数组有相同 长度的多维数组,不管有多少维,只使用一组方括号;交错数组是每个子数组都是独立数组的多维数组,可以有不同长度的子数组,为数组的每一个维度使用一对方括号。
3. 数组是引用 类型,但数组的元素可以是任意类型 ( 值类型或引用类型 ) ,数组实例是继承自 System.Array 的对象。 Rank 属性返回数组的维度数 ( 秩 ) , Length 属性返回数组中所有元素 的个数。
4. 声明时方括号里的逗号是秩的说明符,秩 = 逗号数 + 1 。不能在数组类型中声明维度的长度,秩是数组类型的一部分 ,但维度长度不是 。数组声明后,维度数 ( 秩 ) 固定,但维度长度直到数组实例化时才会被确定 。
5. 数组创建表达式使用 new ,后面是基类名称和一对方括号,方括号中以逗号分隔每一维的长度。注意:与创建对象不同,数组创建表达式不 包含圆括号 。数组每一维的索引从 0 开始。
6. 数组被创建后,每个元素都会被初始化为相应的 0/0.0/false/null 。可以在初始化时设置值,这些值以逗号分隔,并封闭在一组花括号内。维度长度可选,编译器会通过初始值自动判断。数组的声明及初始化语句中只能有一个赋值运算符 ( = ) 。
7. 初始化矩形数组的技巧:逗号不用在左 花括号之间 ,也不用在右 花括号之前 。声明数组时可以省略创建表达式部分 ,如: int[] arr1 = new int[3] {10, 20, 30}; 可以简化为 int[] arr1 = {10, 20, 30} ; 另外还可以使用 var 关键字来声明匿名类型数组,初始化数组时,编译器会自动判断数组类型,如:
int[ , ] intArr3 = new int[ , ] {{10, 1}, {2, 10}, {11, 9}};
var intArr3 = new [ , ] {{10, 1}, {2, 10}, {11, 9}};
注意秩说明符 [ , ] 不能丢。
8. 交错数组是数组的数组,每个字数组长度可以不一样。声明时要求每一个维度有一对方括号,方括号数决定了数组的秩 ,如: int[][][] Arr; 秩为 3 。最左 边的括号 为最高级别 的子数组。不能在声明语句中初始化最高 级别数组之外 的数组。
9. 交错数组的完全初始化不能在一个步骤中完成,每个数组必须独立创建 ,如:
int[][] Arr = new int[3][]; // 先实例化顶层最高级数组
Arr[0] = new int[] {10,20,30}; // 再实例化各个子数组
Arr[1] = new int[] {40,50,60};
Arr[2] = new int[] {70,80,90};
10. 操作交错数组与矩形数组类似,都是使用多层 for 循环,从最高级别数组每一维开始一层一层直至所有子数组的每一维。
11. 交错数组是由多个数组对象 组成的,而矩形数组只有一个对象,所以编程复杂度小。但由于一维数组在 CIL 中有特定的指令用于优化,故使用一维数组组成的交错数组可能会比矩形数组更有效率,因为矩形数组没有这些优化指令。
12. foreach 语句中的迭代变量是临时 的,只读 的,所以不能改变迭代变量,但对于引用类型的迭代变量,虽不能改变它自身 ,但却可以通过它来改变它所引用的数据 ( 对象 ) 。在 C# 3.0 中,还可以使用 var 来声明迭代变量,元素类型由编译器判断。
13. 在多维数组中,元素的处理次序是最右边 的索引号最先递增 。当索引从 0 到长度减 1 ,下一个左边的索引被递增,右边的索引被重置为 0 。一个交错数组是数组的数组,所以必须为交错数组中的每一个维度使用独立的 foreach 语句。 foreach 语句必须嵌套以确保每一个嵌套数组都被正确处理。可参见 P241 代码。
14. 数组协变是指:可以将某个不是数组基类型的对象赋值给数组元素。条件是:数组的元素是引用类型,在要赋值的对象类型和数组基类型之间有隐式 或显式 转换。所以,一个派生类的对象总是可以赋值给用基类声明的数组 。注意:值 类型数组没有协变 。
15. 数组继承自 System.Array ,所以继承了很多有用的属性和方法,静态的: Clear , Sort , BinarySearch , IndexOf , Reverse ,使用静态方法时用 Array 来引用; 实例方法 GetUpperBound 返回的是:指定维度的上限,即这一方向上索引的最大值 ( 长度 - 1) 。
16. 实例方法 Clone 只进行浅复制,克隆值类型数组会产生两个独立数组;克隆引用类型数组会产生指向相同对象的两个数组。 Clone 方法返回 object 类型的引用 ,需强制转换为相应的数组类型。