Welcome

首页 / 软件开发 / C# / Effective C#原则40:根据需求选择集合

Effective C#原则40:根据需求选择集合2010-12-13 博客园 Wu.Country@侠缘译“哪种集合是最好的?”答案是:“视情况而定。” 不同的集合有不同的性能,而且在不同的行为上有不同的优化。.Net框架支持很 多类似的集合:链表,数组,队列,栈,以及其它的一些集合。C#支持多维的数 组,它的性能与一维的数组和锯齿数组都有所不同。.Net框架同样包含了很多特 殊的集合,在你创建你自己的集合类之前,请仔细参阅这些集合。你可以发现很 多集合很快,因为所有的集合都实现了ICollection接口。在说明文档中列出了 所有实现了ICollection接口的集合,你将近有20多个集合类可用。

为了 选择适合你使用的集合,你须要考虑在该集合上使用的操作。为了创建一个有伸 缩性的程序,你须要使用一些实现了接口的集合类,这样当你发现某个假设的集 合不正确时,你可以用其它不同的集合来代替它(参见原则19)。

.Net框 架有三种不同类型的集合:数组,类似数组的集合,以及基于散列值的集合。数 组是最简单的也是一般情况下最快的集合,因此我们就从它开始。这也是你经常 要使用到的集合类。

你的第一选择应该经常是System.Array类,确切的 说,应该是一个数组类型的类。 选择数组类的首要原因,也是最重要的原因是 数组是类型安全的。所有其它集合都是存储的System.Object引用,直到C#2.0才 引入了范型(参见原则49)。当你申明一个数组时,编译器为你的类型创建一个特 殊的System.Array派生类。例如:这样创建了申明并创建了一个整型的数组:

private int [] _numbers = new int[100];

这个 数组存储的是整型,而不是System.object的引用。这很重要,因为你在一个数 组上添加,访问,删除值类型时,可以避免装箱与拆箱操作的性能损失(参见原 则17)。上面的初始化操作创建了一个一维的数组,里面存放了100个整数。所有 被数组占用的内存都被清0了。值类型数组都是0,而引用数组都是null。所有在 数组里的元素可以用索引访问:

int j = _numbers[ 50 ];

另外,访问数组时还可以用foreach迭代,或者使用枚举器:

foreach ( int i in _numbers )
Console.WriteLine( i.ToString( ) );
// or:
IEnumerator it = _numbers.GetEnumerator( );
while( it.MoveNext( ))
{
int i = (int) it.Current;
Console.WriteLine( i.ToString( ) );
}

如果准备存储单一次序的对象,你应该使用数组。但 实际上你的数据结构往往比这复杂的多。这很快诱使我们回到了C风格上的锯齿 数组,那就是一个数组里存储另一个数组。有些时候这确实是你想要的,每个外 层元素都是内层的一个数组:

public class MyClass
{
// Declare a jagged array:
private int[] [] _jagged;
public MyClass()
{
// Create the outer array:
_jagged = new int[5][];
// Create each inner array:
_jagged[0] = new int[5];
_jagged[1] = new int[10];
_jagged[2] = new int[12];
_jagged[3] = new int[7];
_jagged[4] = new int[23];
}
}