当前位置:嗨网首页>书籍在线阅读

21-高手点拨

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

16.6 高手点拨

**本节视频教学录像:1分钟**

在C# 2.0之前,主要可以通过两种方式实现集合。

(1)使用ArrayList。

直接将对象放入ArrayList,操作直观,但由于集合中的项是Object类型,因此每次使用都必须进行烦琐的类型转换。

(2)使用自定义集合类。

比较常见的做法是从CollectionBase抽象类继承一个自定义类,通过对IList对象进行封装实现强类型集合。这种方式要求为每种集合类型写一个相应的自定义类,工作量较大。泛型集合的出现较好地解决了上述问题,只需一行代码便能创建指定类型的集合。

泛型集合大大简化了集合的实现代码,通过它可以轻松创建指定类型的集合。泛型是一种思想,主要体现在算法上,它的最大特点就是在不牺牲效率的前提下实现算法的通用性——真正实现代码的重用,其抽象级别要比面向对象高;泛型是面向算法(过程)编程,脱离数据,实现算法(模式)的重用性。

下面以ArrayList与List为例说明泛型集合的优点及非泛型集合的缺点。例如,有以下这么一段代码。

01  ArrayList numbers = new ArrayList();
02  numbers.Add(22);
03  numbers.Add(35);
04  int number =(int) numbers[1];
05  Console.WriteLine(number);

这段代码的背后会发生什么呢?首先,在ArrayList中将所有元素都看成Object类型的,是引用类型。第一行声明一个ArrayList的对象,第二行和第三行调用Add方法增加两个整数。在这个过程中,整数22和35被CLR装箱(boxing)成object类型的,而在第四行访问第二个元素时又被拆箱(unboxing),装箱与拆箱大体上会发生以下过程。

① 在托管堆中分配一个新的object。

② 基于栈(stack-based)的数据必须移动到刚分配的内存区中。

③ 当拆箱时,位于堆中的数据又得移动到栈中。

④ 堆中无用的数据进行垃圾回收。

当代码中涉及大量装箱与拆箱操作时,必然会影响应用程序的性能。而改用泛型的集合类时,比如用语句:

List<int> numbers = new List<int>();

代替上述第一行,第四行相应改成:

  int number = numbers[1];

就减少了装箱与拆箱的工作,当存在大量数据时,自然可以提高性能。另外,使用泛型集合还能增强数据类型的安全。例如,下面的代码:

01  ArrayList numbers = new ArrayList();        
02  numbers.Add(22);
03  numbers.Add(35.5);
04  numbers.Add(true);
05  for (int i = 0; i < numbers.Count; i++)
06  {
07           Console.WriteLine((int)numbers[i]);
08  }

在编译时是不会报错的,因为可以将int类型、float等数值类型装箱成object,因此即使ArrayList增加的数据类型不一致,编译器也不会提示错误,但是运行时会报错。但是如果使用泛型类型,比如List,那么在编译时就会进行类型检查,防止运行时错误。因此,出于性能和类型安全的考虑,从C# 2.0开始尽量使用泛型版本的集合类型。