第12章 泛型
泛型是CLR和编程语言提供的一种特殊机制,它支持另一种形式的代码重用,即“算法重用”。
对于我来说,泛型用得最多也就是List<T>这种用法,主要是泛型对于值类型的集合来说,可以不用进行装拆箱,并且保证了类型安全。对于传统的非泛型集合,ArrayList里添加的是Object类型,所以使用值类型集合时,就需要装箱,取值时就要拆箱,十分影响性能,同时由于所有类型的基类都是Object,所以可以将不同类型的对象放到同一个集合中,这样在取值时很容易出现类型转换错误。
除此之外,IEnumable<T>的使用也挺多,因为这是LINQ的基础,实现了IEnumable<T>接口的集合都能使用LINQ语法,LINQ对于操作内存提供了很方便的用法。
在目前所在的公司,数据访问层用的就是泛型,先定义一个BaseAccess的基类,再定义一个BaseDAL的派生类,在BaseDAL派生类中编写常见的数据库操作——增删改查。在定义所谓的BLL层时,假如有一个实体类Goods,可以定义其GoodsBLL继续自BaseDAL<Goods>,这样就能重用数据库的操作了,这时有个关键的地方,就是在BaseDAL主要是用到了反射,通过对T类型反射,获取其字段等信息,再进行拼装数据库的各种语句。这也算是“算法重用”吧。
回到正题,用到泛型的还有一个地方,那就是逆变和协变泛型类型。以前还不清楚这种类型是什么回事。自从学习了LINQ之后,就明白了,原来这就是一种委托,根据in和out关键字来定义这个委托的参数和返回值。在c#中,有一种简便的委托定义方式,那就是Func<in T,out TResult>,这在LINQ中很常见,因为LINQ的链式编程中,例如where()方法,where中的参数就是一个Func委托了。
泛型方法用得真不多,还没遇到,也不清楚什么情况下使用。
泛型还能够使用约束,对类型T进行约束,限制其的继承,例如:
public static T Min<T>(T o1,T o2) where T : IComparable<T>
{
if(o1.CompareTo(o2)<0) return o1;
return o2;
}
这就限制了T要继承IComparable这个接口的类型才能使用此方法。
其他就看得不怎么明白,而且没什么例子说明,望以后能够进一步了解。