C#泛型是CLR类型系统的拓展,并且允许开发者定义那些具有不确定细节的类型。为了加强代码的可拓展性,当代码在实际执行时细节才最终确定。
泛型是微软.NET Framework 2.0 的一个特征,并且促使代码运行更快、具有更高的维护性、更强健。
泛型是CLR机制的拓展,允许开发者定义那些具有不确定细节的类型。定义为泛型的变量,其类型在最终执行时才根据特定要求实现其类型。泛型折射为如下特点:使那些可能减少无用细节的代码实现成为可能。这种代码就是泛型。
概览C#泛型
作为任何一种新技术,首先问一下“为何有用”是很有好处的。那些对C++模板熟悉的开发者会发现泛型在代码组织中发挥了一个类似的功能。
然而,因为泛型具有某些附加意义及限制在此并非想对CLR泛型及C++模板做过多的比较。
CLR泛型的强健性表现为:编译时类型的安全、二进制代码的重用、性能及明晰。接下来将简短地描述这些特点,之后你会对此达到更深刻的理解。举例:设定一个拥有两个集的类,SortedList一个特定对象集合;GenericSortedList< T>一个类型T的集合。
类型安全:当SortedList添加了一个字符类型时,存在一个字符向对象的隐式转换。同样,如果自列表检索一个字符类型对象时,存在一个自Object向字符类型的显示转换。这种运行时类型安全的缺乏对开发者及易于出错很不利。相反,使用了GenericSortedList< String>之后所有的添加及查找方法通过字符参数来运行。由此允许程序在编译时而不是运行时对变量类型进行确定及检查。
二进制代码复用:开发者为了维护性可能会选择自SortedList派生一个SortedListOfStrings(或者利用一种安全类型封装SortedList)来达到编译时类型安全。通过这种方法实现的问题在于新代码需要在实现类型安全的列表重写,由此写代码会很吃力。而通过GenericSortedList< T>,所要做的就是实例化预期元素类型T。作为一个附加值,泛型代码产生于运行时,由此两种基于未涉及的类型(例如GenericSortedList< String>和GenericSortedList< FileStream>)能够复用大部分的JIT编译代码。即使扩展是不同的集合,这也可以实现。通过在JIT编译时实现泛型代码的拓展,CLR机制自然减少了对硬盘及内存的膨胀并保持类型不同集合间的转换。
性能:这是软件的基本。如果在JIT编译时而不是在执行过程中进行类型检查,性能会得到提高。在托管代码中,参数及值的实例化需要不断进行装盒及拆盒。避免这样的实例化对性能会有显著影响。一个拥有一百万个整型数的数组排序泛型方法比非泛型方法快三倍。这是因为完全略掉值的装盒步骤。同样对字符参数的数组排序通过泛型方法因不必在运行时进行类型检查,性能会会提高20%。
明晰:C#泛型的明晰有多种形式。首先是限制,限制可以影响泛型代码的扩张;通过泛型,避免了使用C++模板出现的那种未知编译错误。在GenericSortedList< T>例子中,集类的作用范围限定在T能够实现的类型及进行排序。当然泛型方法也可以通过类型接口而不必使用特定语法来使用。由此,在编译时的类型安全增加了程序代码的明晰。本文将详细讲解限制、类型拓展以及类型安全。
C#的Generic、Java的Generic、C++的Template三者的不同
C++的模板及Java的泛型基于各自的编译器。编译器自实例化泛型或模板时构造代码,C++的机制会引起代码膨胀及减少类型重构的顺滑性;Java的泛型本质上是将泛型代码视为一套自动实例化机制,这种机制会引发泛型实例化间的意外类型匹配。
【编辑推荐】