Effective C# Item40 : 根据需要选用恰当的集合

    本条只针对.NET 1.x,因此不会涉及到泛型,讨论的是不全面的。

 

    .NET为我们提供了很多中类型的集合,每种类型都有自己适用的场景,并没有一种类型可以适用于所有场景。这些集合包括:链表、数组、队列、栈等。所有的集合都实现了ICollection接口,因此,我们可以通过查找ICollection接口的方式,比较快速得到所有集合类型,其中IList和IDictionary两个接口都是派生自ICollection接口,IList是值的集合,其元素通过索引进行访问,例如ArrayList;IDictionary是键/值对的集合,例如HashTable。如果上述两种类型的集合都不能满足你的需求,那么你可以直接从ICollection接口创建自己的集合类型。

    在.NET 1.x的年代里,我们最常用的集合类型是数组Array,或者说某种特性类型的数组,之所以最常用,是因为其他类型的集合中的元素都是System.Object类型,在使用时,会遇到频繁的装箱/拆箱操作。在.NET 2.0引入泛型后,其他类型的集合拥有了充分发挥作用的机会。

    关于数组,一个注意的事情:如果数组元素是引用类型,那么使用new的方式初始化数组时,并不会初始化数组元素,这时如果访问数组元素,得到的是null,还需要程序在访问时,执行数组元素的实例化操作。

    对于多维数组,.NET为我们提供了两种不同类型的数组,一种是“锯齿”形式的多维数组,一种是“普遍”意义上的多维数组,声明方式和遍历方式都有区别,请看以下代码。

 

多维数组
1 /// <summary>
2 /// test multi dimension array
3 /// </summary>
4   private static void MultiDimArrayTest()
5 {
6 //锯齿型数组
7   int[][] arrJaggedTest = new int[3][];
8 arrJaggedTest[0] = new int[5];
9 arrJaggedTest[1] = new int[2];
10 arrJaggedTest[2] = new int[4];
11 foreach (int[] arrTemp in arrJaggedTest)
12 {
13 foreach (int nTemp in arrTemp)
14 {
15 Console.Write(nTemp);
16 }
17 }
18 Console.WriteLine();
19 //普通多维数组
20   int[,] arrMulDim = new int[3, 5];
21 foreach (int nTemp in arrMulDim)
22 {
23 Console.Write(nTemp);
24 }
25 }

    可以看出,在遍历时,对于“锯齿”形式的多维数组,每一维都需要使用foreach语句,而对于“普遍”意义上的多维数组,直接使用一个foreach就可以对其进行遍历了。

 

    使用数组带来的缺陷:1. 不能动态的调整大小;2. 不能对数组元素执行动态的插入和删除。

    为了解决第一个缺陷,.NET为我们提供了ArrayList,它基于数组,但是在内部对其大小进行维护,不需要用户关心;针对上述第二个缺陷,.NET为我们提供了字典类型的数据,这中类型的集合采用HashTable的方式存储Key和Value,我们在查找、添加和删除元素时,都会比较方便。

    当我们定义的类型中包含集合时,那么我们应该将集合暴露给用户,有两种方法可以实现这个目的:1. 为类型编写索引器;2. 为类型实现IEnumerable接口。

 

    在实际使用的过程中,采用哪种类型的集合,取决于要执行的操作以及应用程序对空间和速度的整体目标,在大多数情况下,Array类提供了最高效的集合容器(只是针对.NET 1.x来说)。

posted @ 2010-02-22 22:32  李潘  阅读(434)  评论(0编辑  收藏  举报