泛型类介绍

来源:互联网 发布:网络电视批发 编辑:程序博客网 时间:2024/06/05 17:11

列表1 这个控制台应用程序包含一个Customer类和一个基于List<T>的强类型集合Customers。

 

注意,我们有一个强类型集合-List<Customer>-对这个集合类本身来说不需要写一句代码。如果我们想要扩展列表customer,我们可以通过从List<Customer>继承而派生一个新类。
三、 实现一个泛型类

  一种合理的实现某种新功能的方法是在原有的事物上进一步构建。我们已经了解强类型集合,并知道一种不错的用来构建泛型类的技术是使用一个特定类并删除数据类型。也就是说,让我们定义一个强类型集合CustomerList,并且来看一下它要把什么东西转化成一个泛型类。

  列表2定义了一个类CustomerList。后面的部分把CustomerList转化成List<T>。

  列表2定义类CustomerList:

 

四、 定义类头

  如果我们定义一个泛型类,我们需要把类头转化成一个泛型类。所有我们需要做的是命名参数并且把类名改成某种泛型。List<T>只有一个参数T,并且因为我们在以一种向后兼容的方式工作,所以我们知道类名是List。列表3显示出列表2中类的新类头。

  列表3 一个泛型类头显示出参数化的参数T。

 

五、 实现泛型字段

  如果我们需要把任何字段转换成泛型字段,我们将只需简单地把它们的类型改变成T(或该字段所描述的任何参数)。泛型List不需要任何字段,但是假定存在一个私有的整型字段叫foo-我们将把它泛型化。我们将如下重新定义它:

private T foo;

  当参数T被填充到类中时,List T也将因foo被填充。

  六、 定义泛型方法

  接下来,我们为所需要的参数化类型定义其它一些特性。这包括属性,方法,和事件。在我们的实例中,在Customer出现的每一处,我们都用参数T替换它。完成后的泛型列表类显示于列表4中。

  列表4 一个基于System.Collections.CollectionBase的轻量级的参数化泛型列表类。

 

 

为了测试该定制列表,注释掉使用System.Collections.Generic命名空间一句并且把列表4中的List<T>使用在列表1的代码中;它将以同样的方式工作。

  全面地修改.NET的List<T>是不必要的而且它也包含远比我们的示例多得多的特性;但是列表4显示出这种机制对于定义定制泛型类是多么容易。
七、 增加类型约束

  最后要讨论的是约束问题。约束被应用于类或其它特性上并且使用下面的语法:

Where T : constraint_type

  例如,任何我们想要通过using语句所使用的,如一个SqlDataReader,必须实现Idisposable接口。这是因为如下方式使用的using语句:

using(Form f = new Form()){...}

  就象一个try..finally块一样工作-总是清除新创建的资源。其工作原理很简单,只需要CLR针对在该using语句中创建的对象发出一个到IDisposable.Dispose的调用即可。例如,在上面这一句中,一个新的表单被创建,并且在using语句退出之前即调用Form.Dispose。
要对一个泛型类施加以确保该类实现了接口IDisposable,我们将添加先行词where T:Idisposable。在列表4中的泛型列表上施加约束后,我们将重新修改列表4如下面的列表5所示。

  列表5 增加一个约束到泛型类以确保我们的List<T>中的所有的值T实现接口Idisposable。

 

 

先行词where的值可以是类,接口,结构,实现一个无参的公共构造器或有一个特定的基类的类。详见有关帮助文档。

  八、 总结

  泛型的设计是用来减少你重复实现的代码的次数-只需改变数据类型即可。因为抽象数据结构,如队列,栈和列表皆是典型的数据结构,所以存在针对这些东西的泛型类完全可以理解。你可以从.NET中派生大量的值-通过使用现有的泛型类,如在System.Collections.Generic命名空间中的那些。

  可以肯定,在一段相当长的时间里,泛型将会象模式和重构等革新一样对开发带来越来越大的价值,而且新的数据结构能被转换成可重用的如泛型等的代码元素。