从VB、C#到VB.net,在变量的使用中总少不了数组的影子,它不仅可以快速而容易地从头到尾遍历元素,还可以快速的修改元素。但是用的多了自然就发现了的它的缺点,当两个元素之间添加元素时就比较困难了,因为在创建时事先指定了数组变量的大小使用时又不能随意增改,再加上链表、堆、栈等需求的增加,数组已经显得力不从心了,由此发展出了集合,即传说中的动态数组,它是.NET Framework提供的用于数据存储和检索的专用类,这些类提供了对堆栈、队列、列表和哈希表的支持。
但是集合都依赖于Object基类,使用时集合中的元素都得转为Object,这其中涉及到了拆装箱的问题(大量的计算),且集合中的元素类型不一定一致从而可能会带来安全隐患。为了解决集合的不足之处,又引入了泛型集合,它把里边的元素强制指定为特定的类型(也可以说是模板),是集ArrayList集合和Array数组优点于一身的好东西。
1.数组
System.Array类是数组的基础,数组是由它派生而来的。所有.Net数组和集合的下标从0开始,数组的使用比较简单,以前VB等编程语言中已经用过n多次,这里不再赘述了。
2.集合——ArrayList
集合(Collections)名称空间是System名称空间的一部分,System.Collections名称空间提供了几个类来满足不同的需求,目前为止接触过得只有ArrayList类,现在只以它为例来了解集合。
1)ArrayList是一个数组实现IList接口,其大小在添加元素时自动增加大小。ArrayList的容量是其可以保存的元素数,默认初始容量为0,随着元素添加到ArrayLIst中,容量会根据需要重新分配自动增加。
2)使用整数索引可以访问此集合中的元素,索引从0开始。
3)接受Nothing作为有效值并且允许重复的元素。
4)由于实现了IList,所以ArrayList提供添加、插入或移除某一范围元素的方法。
例子:创建一个动物集合
Imports System.Collections '添加集合类的命名空间 Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnAdd.Click Dim arrayAnimal As New ArrayList() '实例化ArrayList对象,不用指定arrayAnimal的大小 Dim animalItem As Object arrayAnimal.Add("小猫") '调用集合的Add方法增加对象 arrayAnimal.Add("小狗") arrayAnimal.Insert(1, "小鸭") '在索引0处添加鸭子 '把集合中的元素遍历显示出来 For Each animalItem In arrayAnimal MessageBox.Show(animalItem.ToString()) '弹出框依次显示:小猫、小鸭、小狗 Next End Sub End Class
3.泛型
1)泛型在很大程度上弥补了集合的缺点,所以在此我们先了解下集合的一些缺点来源
(1)拆装箱
装箱:值类型存储在栈上,应用类型存储在堆上。当值类型想应用类型转变,即从栈向堆上转移,这时值就变成了一对象,就好像值类型外面包装了一层东西,这个过程叫装箱
拆箱:当需要集合中的元素时,需要把箱子从堆上转移到栈上,即引用类型变成值类型,这个过程叫拆箱。拆装箱需要耗费资源和时间。
(2)类型不安全
集合在编译时缺少类型检查。同一个集合可接受不同的元素类型,所有项都强制转换为Object,在编译时无法检查是否可以接受该元素,因为在它眼里所有元素都是Object都是可接受的,这样就使得检查错误变得更难。
2)泛型的引入
鉴于以上的一些缺点,泛型对其中的类型进行了限制,使之成为统一的类型,可以创建一个更安全且更快速的列表。泛型的主要目的是创建强类型化的集合,泛型允许定义代码模板,然后使用这个模板声明变量,实际上是创建一个新的数据类型。.Net基类库中有很多泛型模板,多位于System.Collections.Generic名称空间,所以在使用泛型时需要引用相应的名称空间。
泛型通常使用List(of T)形式,List是类型(或者类)的名称,字母T是点位符类似于参数。它表示必须用力定制泛型的特定类型值,同时也限定了它只能是这个类型。通常情况下,在程序中可以使用集合数据类型的地方都建议使用泛型集合代替。
小结:
集合和泛化在《大话设计模式》这本书中已经接触过,但是当时没有仔细看过,这篇博客权当拾遗补缺。在接下来的机房重构中将会大量的使用泛化,所以后续博客中再举例泛化的使用。
数组、集合与泛化