在泛型之前,通用化是通过在类型与通用基类型 Object 之间进行强制转换来实现的: 即.NET Framework 基类库中的 ArrayList 集合类。ArrayList 是一个使用起来非常方便的集合类,无需进行修改即可用来存储任何引用或值类型。 但是 添加到 ArrayList 中的任何引用或值类型都将隐式地向上强制转换为 Object(引用类型)。
应用实例:
ArrayList list1 = new ArrayList();
list1.Add(3);
list1.Add(105);
ArrayList list2 = new ArrayList();
list2.Add("It is sunny.");
list2.Add("It is warm .");
如果项是值类型,则必须在将其添加到列表中时进行装箱操作(值类型->引用类型),在检索时进行取消装箱操作(引用类型->值类型)。强制转换以及装箱和取消装箱操作都会降低性能;在必须对大型集合进行循环访问的情况下,装箱和取消装箱的影响非常明显。
另一个限制是缺少编译时类型检查:因为 ArrayList 将把所有项都强制转换为 Object,所以在编译时无法防止客户端代码执行以下操作:
ArrayList list1 = new ArrayList();
list1.Add(3);
list1.Add("It is raining in Redmond.");
list1(0)+list1(1);
尽管将string类型和 int类型组合在一个 ArrayList 中的做法在创建异类集合时是完全合法的,有时是有意图的,但这种做法更可能产生编程错误,并且直到运行时才能检测到此错误。
所以从安全和性能的角度考虑,泛型为ArrayList 提供了一个 type parameter类型参数,这样在创建这些类的实例时指定要使用的具体数据类型,避免了向上强制转换为 Object,同时也使得编译器可以进行类型检查。
在 N:System.Collections.Generic 命名空间的泛型 List<T> 集合中,向该集合添加项的操作类似于以下形式:
List<int> list1 = new List<int>();
list1.Add(3);
list1.Add("It is raining in Redmond."); //此时系统会报错
因为在创建list1实例时,已经确定该集合的类型为int型,所以只限制添加int类型,当添加string时系统便会编译报错,提高了安全性。
所以相比较ArrayList集合,泛型是更安全并且速度更快的列表,特别适用于列表项是值类型的情况。