设为首页 加入收藏

TOP

理解C#泛型
2015-02-15 13:01:38 来源: 作者: 【 】 浏览:30
Tags:理解 泛型

在C# 2.0中引入了泛型,泛型的出现解决了编码中的很多问题。相信大家一定经常用到"System.Collections.Generic"命名空间中的泛型集合类("Generic"就是泛型的意思)。在C# 1.0中,我们还在使用"System.Collections"命名空间中的非泛型集合类,那么看看我们在没有泛型的时候遇到的问题。


问题1:强制类型转换


在使用非泛型集合ArrayList时,所有的对象都是以object类型加入ArrayList,当对象从ArrayList取出的时候也是object类型,这时我们就需要进行强制类型转换,如果转换不当,就会得到一个运行时的错误;即使我们向ArrayList添加不同类型的对象时,也不会报错(例如上面向stuList中加入了一个int值)。


问题2:装箱和拆箱


在上面的例子中,如果我们使用ArrayList存放一组值类型的数据(例如一组int值),存入时,每个值类型的数据都要进行装箱为object类型;取出时,每个object类型的数据又要进行拆箱操作。


可以看到,在使用非泛型集合的时候,用户需要自己进行类型转换,并且可能遇到运行时的类型转换异常;同时,对于值类型的操作 ,非泛型集合会有装箱和拆箱带来的效率问题。


?


对于上面的问题,我们可以使用C# 2.0中的泛型集合。


这样一来,我们就通过类型参数(例子中的Student)来限制List可以包含的实例类型,从而避免的强制类型转换。


同时,通过类型参数,编译器可以进行类型检查,当试图往List中存入一个与类型参数不匹配的对象的时候,编译器就是给出错误提示。



?


下面我们看看泛型中的一些概念和术语。


泛型有两种表现形式:泛型类型(包括类、接口、委托和结构,没有泛型枚举)和泛型方法。在泛型类型和泛型方法中都会有类型参数,当通过泛型类型实例化对象或者对泛型方法调用的时候,都需要使用一个真实的类型来代替类型参数。


类型参数是真实类型的占位符,在泛型声明过程中,所有的类型参数放在一对间括号中(<>),通过逗号分隔。


根据类型参数不同的指定类型实参的情况,泛型类型可以分为:


类型是对象的蓝图,我们可以通过类型来实例化对象;那么对于泛型来说,未绑定泛型类型是以构造泛型类型的蓝图,已构造泛型类型又是实际对象的蓝图。


下图就是一个简单的例子,Dictionary就是一个泛型类型(未绑定泛型类型,开放类型);通过制定类型参数,可以得到不同的封闭类型;通过不同的封闭类型有可以构造不同的实例。



我们都已经习惯了方法的参数和返回值拥有固定的类型,这里就看看“参数化”的方法。对于泛型方法,可以理解为拥有类型参数的方法。


对于上面例子中Dictionary这个泛型类型,有很多方法可以使用,例如:


注意,这些方法中没有一个是真正的泛型方法,他们只是使用了泛型类型的类型参数


真正的泛型方法应该拥有自己的类型参数,当我们使用泛型方法的时候,要给泛型方法的类新参数指定类型实参,接下来看一个泛型方法的例子。


在上面的例子中,我们使用泛型方法来实现一个两个元素比较的例子,我们看到方法"GetBiggerOne"拥有自己的类型参数,当我们看到一个泛型方法时,可以一步步用真实的类型替换泛型方法中的类型参数,这样就会简化我们的分析。


对于泛型的类型约束,将在下面一篇文章介绍。



根据上面的分析,可以看到泛型有一些的优点:


泛型的出现,给我们带来了很多好处,泛型实现了类型和方法的"参数化"。


基于泛型,我们可以实现代码重用,并且泛型为我们提供了类型安全检查。对于值类型的操作,通过泛型可以避免装箱和拆箱带来的性能损失。


同样C# 2.0 以后,就建议只在代码中使用支持泛型的集合类了(System.Collections.Generic)。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇堆排序的分析及实现 下一篇《APUE》进程环境

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: