首页 > 代码库 > 集合与泛型

集合与泛型

hi,you guys。

今天我们继续学习<叩响c#之门>,今天我们学习的内容是集合与泛型。集合、泛型是我们项目开发中经常会用的知识。学好泛型、集合,对我们开发工作有很大的帮助。

集合

 

物以类聚,相同的东西需要归于一类。我们常常将相互关联的对象组成集合,自然数组成自然数集。同班同学组成班级,诗人做的诗篇,组成诗集。集合中的对象,称为元素(Element)。C#为我们提供一组功能强大的集合类,实现了多种不同类型的集合,我们可以根据实际用途选择恰当的集合类型。下表,是FCL(Framework Common Library)类库为我们提供的部分集合类。

QQ Photo20140823155454

除了Array在System命名空间下,其余的类都位于System.Collections命名空间下。这些类通过直接或间接的继承一些接口,来实现其自身强大的功能。我们之前在项目中用过foreach循环语句,遍历一个集合或数据集。那么是如何foreach是如何实现对集合或数据集的遍历的呢?(与其说是遍历,不如说是迭代。关于迭代概念,大家可以参考一些数据结构书籍的递归算法)。原来FCL提供的集合类,都直接或间接的实现了IEnumerable接口,这个接口声明了一个名为GetIEnumerator()方法。这个方法返回一个继承了IEnumerator接口的类,我们通常将这个类称为迭代器。

//IEnumerable接口public interface IEnumerable{     IEnumerator GetIEnumerator();}

IEnumerable接口类

//IEnumerator接口public interface IEnumerator{     bool MoveNext();      //获取下一个元素     object Current{get;}  //获取当前元素      void Reset();        //将枚举数设置为其初始位置}

IEnumerator接口类

foreach语句就是通过访问迭代器来获取集合中的元素。ICollection接口也是一个很基础的接口,它继承了IEnumerable接口,并且添加了一个Copy()方法,和一个Count属性以及两个用于同步的属性。

//ICollection接口public interface ICollection:IEnumerable{     void Copy(System.Array array,int index);  //复制到数组      int Count{get;}                           //元素个数     bool IsSynchronized;                      //是否同步    object SyncRoot{get;}                     //用于同步的对象   }

IList接口、IDictionary接口都继承于ICollection接口。

关于各个集合类的一些方法,大家可以下去自己练习一下。因为,本章主要讲解的是泛型类。其实,在项目中大家更多的会去使用泛型,因为集合存在一个弊端。

 

集合类的弊端

 

大家看看下面的代码:

 ArrayList list=new ArrayList(); lsit.Add(10);         //添加元素 int n=(int)lsit[0];   //取出元素

 

因为所有类型都继承于object的类型,所以当我们调用.Add()方法,向集合中添加元素时,系统会默认为object类型。此时,如果添加的元素不是引用类型而是值类型,那么在向集合添加元素时,就会进行装箱操作,将值类型转换为引用类型。同样,在我们读取元素时,需要拆箱操作,将object的类型转换为值类型。这样做,会有三个缺点:

第一、在装箱、拆箱的过程中,可能会造成一定的性能损失。

第二、什么类型的数据都往集合中放,不利于编译器进行严格的类型安全检查。

第三、显示转换类型,降低了程序的可读性。Note(现在计算机越来越快,性能也不是唯一目标了。软件开发成本在于软件维护与升级。所以,提高代码可读性可以降低软件开发成本呢。)

 

ArrayList   list=new ArrayList();list.Add(10);list.Add("hello");foreach(int element in list){   int n=(int)element;}

上面这段代码,编译不会出错。运行会出现,因为”hello”不能转换为int类型。现在大家看出集合类的弊端了吧,那么泛型类又有什么地方强于集合呢?其实不难想象,泛型强于集合的地方,一定是集合比较薄弱的地方。集合薄弱的地方就在,集合类的元素类型没有限制。

 

泛型

 

泛型与集合的功能基本一致,唯一的不同点在于,泛型类的元素类型受我们控制,是我们指定的类型,而不是万物之祖的object类型。泛型具有一个参数列表<T>,在整个类里用T代表元素类型,T的类型是不确定的,是抽象类型。在我们实例化类时,将抽象类型的元素具体化,具体类型的参数将代替T。看程序:

// 泛型类 public class  Generic<T>{       public void Check()        {           Console.WriteLine(this.GetType()); //输出T的类型                 }     }//实例化泛型类Generic<int>  instanceInt=new Generic<int>(); instanceInt.Check(); //输出的类型为System.Int32Generic<String>  instanceString=new Generic<String>();instanceString.Check();  //输出的类型为System.String;

  泛型类中的T,是抽象类型。实例化时,才会将其具体化。例如上面的instanceInt,就是将泛型类中的T,具体化为Int类型。instanceString,就泛型类的T具体化为String类型.我们可以定义泛型类,同意也可定义泛型方法,泛型接口等。看下面的代码:

 

//泛型类public static void Swap<T>(ref T a,ref T b){        T t=a;         a=b;         b=t;}

此时的a,b都是抽象的,都是未知的类型。

Static void Main(string[] args){   int x=100;   int y=200;  Swap<int> (ref x,ref y);Console.WriteLine("x={0},y={1}",x,y);}

我们在调用泛型方法时,将参数具体化了。

C#为我们提供了一些泛型类:

List<T>
Stack<T>
Queue<T>
SortedList<TKey,TValue>
Dictionary<TKey,TValue>

关于他们的一些方法,大家可以查看相关手册。学会通过查看手册来学习编程,是很重的。好了今天的泛型、集合就到这里了。最后,我把作者讲的一句话,给大家分享一下。“实践中磨练编程技能,思考中感悟编程本质”。

集合与泛型