CLR支持两种复合类型,一种是其成员可以通过局部的惟一名称访问,另一种是其成员没有被命名,而是通过位置被访问。类和结构体就是前者的例子,数组是后者的例子。
数组是引用类型的实例。这个引用类型是CLR基于数组的元素类型和数组的维数[也称为秩(rauk)]合成的(synthesized)。所有的数组类型都继承了内置类型System.Array,如示例5.11所示。这意味着System.Array的所有方法对于任何类型的数组都是隐式可用的。这还意味着只要通过声明一个System.Array类型的参数,就可以让一个方法接受任何类型的数组。从根本上讲,System.Array所标识的对象子集才是实际的数组。
示例5.11 System.Array(节选1)
Namespace System{
Public class Array{
//长度/形式属性
Int Length{get;}
Int Rank{get;}
Int GetLength(int dimension);
//get访问器
Object GetValue(int i);
Object GetValue(int I,int j);
Object GetValue(int I,int j,int k);
Object GetValue(int[] indices);
//set访问器
Void SetValue(Object value,int i);
Void SetValue(Object value,int I,int j);
Void SetValue(Object value,int I,int j,int k);
Void SetValue(Object value,int[] indices);
}
};
数组类型有其自身的类型兼容规则,这些规则基于元素类型和数组的形式(shape)。数组的形式由维数及每维的容量组成。对于如何确定数组类型的兼容性,我们说, 元素类型和维数相同的数组是类型兼容的( type-compatible)。如果两个数组的元素类型都是引用类型,则需要考虑额外的兼容性。
假设一个元索类型是引用类型(T)的数组,它要与相同维数的元素类型为v的数组兼容,则要求类型T与类型v是兼容的。这意味着所有一维数组(其元素类型是引用类型)与System.Objct[]是类型兼容的,因为所有可能元素类型本身与System.Object都是类型兼容的。图5.12说明了这个概念。
大多数编程语言都有几种数组类型。将语言级别的数组语法映射到CLR数组类型是编译器的工作。在CLR中,数组是引用类型的实例,并且有方法、属性和接口。因为数组是引用类型,所以,数组可以在任何需要System.Object类型的地方被高效地传递。在使用时独立于编程语言的是,你总是可以通过使用Length属性得到数组元素的总数。
每种编程语言都提供了其自身的语法,用于声明数组变量、初始化数组和访问数组元素。下面的c#程序片段创建并使用了一维整型数组
//声明int32数组的引用
Int[] rgn;
//分配9个元素的数组
Rgn=new int[9];
//遍历所有元素(下标从0一直到8)
For(int i=0;i<rgn.length;++i)
{
Rgn[i]=(i+1)*2;
}
因为数组是引用类型,所以这个例子中的rgn变量是一个引用。用于数维元素的内存将被分配在堆上。
c#编程语言支持多种初始化数组的语法。下面的三种方式产生相同的冗长的
//冗长的
Int[] a=new int[4];
For(int i=0;i<a.length;++i)
{
A[i]=[i+1]*2;
}
//紧凑人
Int[] b=new int[]{2,4,6,8};
//极端紧凑的
Int[] c={2,4,6,8}
上面所列出的紧凑版的好处是:右边的初始化语句是个有效的c#表达式,并且可在任何期望int[]的地方使用。z
NN噀6ehV?^諷坢b€cw?u
ghV
NN噀6ehV@bZP剉