C#集合类型初探(3)(强类型集合、为何需要泛型)
时间:2011-05-25 来源:乌冻
C#集合类型初探(3)
3、强类型集合基类
在之前介绍的集合类中,大多数其中的元素或值存放的都是Object类型,所以允许用户向其中放入任何C#中合法的类型。有的时候,我们却需要这样的一个集合,元素(Key和Valu)中只允许存放特定的数据类型, 那么这时候我们就需要一种强类型的集合类型。
在System.Collections命名空间中,提供了3个抽象的基类,它们分别是:
--> 强类型集合抽象基类CollectionBase--继承IList接口
--> 键/值强类型集合抽象基类DictionaryBase--继承IDictionary接口
--> 强类型只读集合抽象基类ReadOnlyCollectionBase--继承ICollection接口
这些基类为我们提供了创建强类型集合的一些基本功能,所以使用它们对进行派生扩展后,能很方便的创建一个强类型的集合类。这三个类都是抽象类(abstract),只能被继承,本身不能实例化,他们的实现原理和使用方式都基本一致,这里只介绍DictionaryBase基类。
DictionaryBase基类的属性
名称 |
说明 |
Count |
获取包含在DictionaryBase实例中的元素数 |
Dictionary |
获取包含在DictionaryBase实例中的元素的集合 |
InnerHashtable |
获取包含在DictionaryBase实例中的元素的集合 |
--> Dictionary和InnerHashtable方法获取的是相同的对象,这个对象是在DictionaryBase中已经实现了的一个DictionaryEntry对象的集合,这个对象集合类同样继承IDictionary接口。
--> 在DictionaryBase中有一些比较特殊的保护方法,这些方法都是以On开头,这些方法的功能是在执行某个操作之前或者之后能够被自动调用的方法。而用InnerHashtable属性获得的对象集合在进行增加插入等操作时,不能触发这些On开头的方法,所以大多数时候,我们都用Dictionary属性来获得对象集合。
DictionaryBase基类的显示接口实现
名称 |
说明 |
获取一个值,该值指示对 DictionaryBase 对象的访问是否同步(线程安全)。 |
|
获取一个对象,该对象可用于同步对 DictionaryBase 对象的访问。 |
|
将带有指定键和值的元素添加到 DictionaryBase 中。 |
|
确定 DictionaryBase 是否包含特定键。 |
|
获取一个值,该值指示 DictionaryBase 对象是否具有固定大小。 |
|
获取一个值,该值指示 DictionaryBase 对象是否为只读。 |
|
获取或设置与指定的键相关联的值。 |
|
获取包含 DictionaryBase 对象中的键的 ICollection 对象。 |
|
从 DictionaryBase 中移除带有指定键的元素。 |
|
获取包含 DictionaryBase 对象中的值的 ICollection 对象。 |
|
返回循环访问 DictionaryBase 的 IEnumerator。 |
--> 通过DictionaryBase中这些显示地实现的接口成员,就能方便的扩展我们自己定义的派生类,以达到我们想要的强类型集合类。
至此System.Collections命名空间中的相关接口和类都已介绍完毕,而System.Collections.Specialized命名空间中提供的类由于使用限制多,运用范围窄,本文就不多做介绍。
三、为何需要泛型?
1、装箱和拆箱
在.NET中,将类型分成值类型(value)和引用类型(regerence type)。值类型包括:原类型(Sbyte、Byte、Short、Ushort、Int、Uint、Long、Ulong、Char、Float、Double、Bool、Decimal)、枚举(enum)、结构(struct)。引用类型包括:类、数组、接口、委托、字符串等。
之前说过,大部分的集合,其存放的都是Object类型的元素,也就是引用类型的数据。那么,当把一个值类型的数据放入一个集合的时候,此时就需要将值类型包装成引用类型,这个过程就叫做装箱(boxing)。而从集合中取出该数据时,取出的是引用类型,那么又需要把该数据从引用类型还原为值类型,这个过程就叫做拆箱(unboxing)。
而不管是装箱和拆箱操作,都会导致数据拷贝或者内存分配这些比较影响性能的操作,当集合中的数据规模比较大时,将会对程序的性能产生很大的负面影响。
2、强类型集合
为了解决装箱拆箱的问题,可以使用在第二部分中介绍的强类型集合基类派生出的强类型集合。但使用强类型集合,同样会引发其他问题:
在一个程序中,我们需要的数据结构、数据类型是难以预测的,而且极有可能需要存放多种不同数据类型的集合,在这些情况下,我们就需要为不同的数据集合派生各不相同的强类型集合类。这会使我们的代码非常臃肿,而且需要耗费大量的工作。
在这些情况下,泛型应运而生,在2.0版本开始,C#提供了对泛型的支持。很好的解决了上述的问题。