数组:包含一组类型相同的多个数据结构,可以通过数组的索引来访问数组的变量。数组是由各个“元素”组成,数组里的每一个对象都被称作一个“元素”。数组内部的所有元素要有同一个类型,数组的类型可以是任意 .NET Framework 支持的数据类型。声明数组的方法如下:
数据类型[ ] 数组名 = new 数据类型 [ 数组长度 ];
数组是引用类型,因此数组变量的声明只是为数组引用的实例留出空间。实际的数组实例是在实例化的时候创建的。从使用new关键字创建开始,数字的长度就是固定不变的。数组的每一个元素对应一个索引,数组的索引从0开始,最后一个索引是数组的length(长度)-1;访问数组的元素时使用运算符[ ],,如下面代码所示:
string[ ] name = new string [ 4 ] ;
name[ 0 ] = " 张三 " ;
name[ 1 ] = " 李四 " ;
for ( int i = 0 ; i < name.Length ; i ++)
{
Console.WriteLine (" 姓名是:{0}", nane [ i ] );
}
数组都是从 System.Array 类派生而来的,存在从任何数组类型到 System.Array 的隐式转换,System.Array 类用作CLR的数组基类。Arrey 类是一个抽象的基类,我们不能用对Array 进行实例化的方法来创建Array类的实例:
Array myarray = new Array ();
但是Array提供了一个CreateInstance 的方法来构建数组,语句如下:
Array arr = Array.CreateInstance( typeof( string ),4 ) ;
该语句创建了一个数组,数组的名字是arr,数组类型是string长度是4。
集合:组合在一起的数据组,是组合在一起的类型化数据对象。数据是最基本、最常见的集合。如果将紧密相关的数据组合到一个集合中,则能够更有效的处理这些紧密相关的数据。使用集合的好处就是可以使用相同的代码来处理一个集合中所有的元素,而不需要编写不同的代码来处理每一个单独的元素。集合的操作一般是添加、修改、移除某一个元素或者某一个范围的元素等。
ArrayList
ArrayList实现了一种可变长度的数组,ArrayList 集合属于 System.Collections 命名空间,ArrayList 是一种大小可按需动态分配的数组,定义一个ArrayList的语法如下:
ArrayList 1st = new ArrayList();
ArrayList 1st = new ArrayList();
定义ArrayList的时候可以指定容量,也可以不指定容量,为ArrayList增加元素使用ArrayList的Add方法,代码如下:
ArrayList 1st = new ArrayList();
1st .Add( " 张三 " ) ;
1st .Add( 3 ) ;
注意:ArrayList的Add方法可以添加 object 类型的数据,也就是说可以添加任何C#支持的数据类型。如果添加的是值类型,就会被自动的转换为引用类型,实际上,ArrayList添加后的每一个元素都是引用类型。Add方法返回一个int类型数据,表示所添加元素的索引,Add 方法把所添加的数据直接添加到集合的末尾,如果想为集合的指定位置添加元素的话,可以使用 insert 方法,代码如下:
1st .insert (3 ," 张三 " );
该方法有两个参数,第一个参数是要添加的索引位置,第二个参数是要添加的对象,该对象以后的元素索引自动后延。
ArrayList 的 Count 属性是当前ArrayList包含的元素的数量,注意这个属性是只读的,和Array 是有区别的,Array 对应的属性是 Length 。
ArrayList 的 Capacity属性是能够包含元素的最大数量,在定义开始时,Capacity 为0,当添加一个元素以后,Capacity 就变成4,当添加的元素个数大于4的时候,Capacity 变为8,依此类推。大家可能会认为这其中有的容量会浪费的,解决的办法就是:ArrayList中有个Tr imToSize 方法,这个方法用于将ArrayList容量固定到实际元素的大小,当动态数组元素确定不再添加的时候,可以调用这个方法来释放空余的内存。
注意:Capacity 是ArrayList的容量,是指一个ArrayList中能添加多少个元素,而ArrayList的Count属性是指元素的个数,是集合中实际存在的元素个数。
访问ArrayList中的元素的时候,可以通过索引来访问,但在提取元素的时候需要做类型转换。如下:
for ( int i = 0 ; i < 1st . Count ; i++ )
{
reader per = ( reader )1st [ i ] ;
per.Say();
}
另外我们还可以通过foreach 的方式遍历ArrayList中的数据对象,代码如下:
foreach ( object read in 1st )
{
reader per = ( reader )1st [ i ] ;
per.Say();
}
这两种遍历方式的输出结果是一样的,只不过for循环通过索引访问元素,而foreach是通过对象来访问元素的。
ArrayList 集合同时支持两种删除操作,按索引删除和按对象删除,这两种方法都是删除ArrayList的具体某一个元素,如果要删除全部元素,可以使用Clear方法。代码如下:
ArrayList 1st = new ArrayList();
reader red = new reader (" 张三 ",20) ;
1st .Add ( red ) ;
索引删除: 1st .RemoveAt ( 0 ) ;
对象删除: 1st .Remove ( red ) ;
全部删除: 1st.Clear ( ) ;
注意:在删除ArrayList的元素时,集合的索引会自动调整。
Hashtable
hashtable(哈希表)是C#中另外一种集合的存取方式,hashtable是目前检索速度最快的数据组织方式。hashtable是使用键 / 值对的方式来对集合进行管理,键和值是一一对应的,在hashtable(哈希表)中不能出现相同的键。
hashtable和ArrayList一样也属于System.Collections命名空间,它的每一个键对应一个值,给hashtable添加元素的时候也是使用Add方法,只不过它的Add方法有两个参数,一个是键,另一个是键对应的值。语法如下:
hashtable ht = new hashtable () ;
ht . Add( object key , object Value ) ;
查看hashtable中的数据元素的数量,使用Count属性。代码如下:
Console.WriteLine ( " 共有读者{0}人 ",ht.Conut ) ;
如果添加的元素已经存在则会产生异常,所以要先使用 ContainsKey 方法判断键是否存在,ContainsKey 方法需要一个参数作为要检索的键名,返回一个布尔类型值,如果查询的键存在返回“true”,否则返回“false”。代码如下:
ht .ContainsKey ( "张三" ) ;
由于hashtable添加数据的方式是键和值对,没有索引,所以我们不能通过索引的方式来遍历hashtable,所以不能和ArrayList一样使用for循环,但可以使用foreach或者是while 的方式来遍历:
使用 foreach:
通过遍历值取值: foreach ( object obj in ht.Values )
{
reader myreader = ( reader )obj ;
myreader.Say();
}
通过遍历键取值: foreach ( string name in ht.Keys)
{
reader myreader = (reader)ht [ name ] ;
myreader.Say();
}
使用while:
IDictionaryEnumerator ie = ht . GetEnumerator();
while( ie.MoveNext() )
{
通过遍历值取值: reader myreader =( reader ) ht [ ie.Key ] ;
通过遍历键取值: reader myreader=( reader ) ie.Value;
}
注意:使用while方式必须先实现 IDictionaryEnumerator接口,使用接口中的两个属性“Key” 和“Value”,这两个属性分别表示实现该接口的hashtable的“Key”和“value”。
删除hashtable中的元素方法和ArrayList有一定的区别,因为hashtable的元素不能通过索引删除,只能通过键来删除,如果要删除的键不存在不会出现问题。如果要清除所有的元素,也是用Clear方法。
泛型和泛型集合
泛型:是C#2.0和公共语言进行时(CLR)中的一个新功能,泛型将类型参数的概念引入到 .NET框架,类型参数使得客户在声明的时候能定义参数类型,而无需在运行时进行装箱或拆箱的操作,从而节约成本,也避免了类型错误的风险。它的最著名的一个用法就是创建集合类,泛型集合同时具备可重用性,类型安全和效率高的特点,这都是传统集合不能具备的。.NET2.0框架提供可一个新的命名空间System.Collections.Generic,其中包含了几个新的基于泛型的集合类,使用泛型集合能提供更好的类型安全。在某些情况下还能提供更好的性能,尤其集合中存储的是值类型的时候,这种优势更明显。因为不需要装箱和拆箱。
泛型集合List<T>
泛型集合和非泛型集合是对应的,Lise<T>对应于ArrayList,List<T>的用法十分类似于ArrayList,其中参数T表示要在集合中添加元素的类型。声明一个List<T>的方法如下:
List<T> 1st = new List<T>();
泛型集合必须要先实例化,注意最后加上“()”,“<T>”可以对集合的类型进行约束。如下面的代码,声明一个包含读者对象的泛型集合方法,集合中只能添加reader类型的元素:
List<reader> 1st = new List<reader>();
由于List<T>对添加的元素类型进行了限制(reader),所以在添加不同类型的(Book)会产生类型不一致的错误。
List<T>和ArrayList的对比:
不同点 相同点
List<T> 对保存的对象类型约束 通过索引访问元素
添加 / 访问元素无需装 / 拆箱 添加方法相同
ArrayList 可以添加任何类型 删除方法相同
添加 / 访问元素需要装 / 拆箱
泛型集合Dictionary<k , v>
Dictionary<k , v>shi C#中另外一种泛型集合,她具有泛型的全部特征,编译时候检查类型,获取元素时候无需类型转换,存储数据的方式和哈希表类似,也是通过键 / 值来保存访问元素的。定义一个Dictionary<k , v>的语法如下:
Dictionary<k , v> dic = new Dictionary<k , v>();
“< k , v>”中的k表示键的类型,v表示值的类型,他们的含义是List<T>是相同的。Key是string类型,value是reader类型,Dictionary<k , v>的使用和哈希表很相似。
Dictionary<string , reader>的键是string类型,存储的读者编号,值是reader类型,存储的是读者对象,如果添加其他类型,编译不能通过。