C++ Java C#泛型
泛型概述
C#中的泛型
C#泛型和java泛型的比较
C#泛型和C++模板的比较
C#泛型中的约束
泛型概述
Bruce Eckel :您能对泛型做一个快速的介绍么?
Anders Hejlsberg : 泛型其实就是能够向你的类型中加入类型参数的一种能力,也称作参数化的类型或参数多态性。最著名的例子就是List集合类。一个List是一个易于增长的 数组。它有一个排序方法,你可以为 它做索引,等等。现在,如果没有参数化的类型,那么不论使用数组还是使用List都不是很好。如果你使用数组,你能获得强类型,因为你可以声明一个 Customer类型的数组,但你失去了可增长性和那些方便的方法;如果你使用一个List,你能够得到所有的便利,但你失去了强类型。你难以说出一个 List是什么(类型的)List,它只是一个Object的List【译注:“什么类型的List”指的是List存放的元素是什么类型的】。这会给你 带来麻烦 ,因为类型只能在运行形时进行检查,也就是说在编译时不会进行类型检查。就算你硬要把一个Customer放进一个List并试图从中得到一个 String,编译器也不会不高兴。在运行之前你根本无法发现它不能工作。同时,当你将简单类型【译注:指值类型】放入List时,还必须对它们进行装 箱。正是由于这些问题,你不得不在List和数组之间徘徊,你经常要很痛苦地决定应该使用哪一个。
泛型的伟大之处在于你现在可以尽情地享受你的蛋糕了,因为你能够定义一个List(读 作:List of T)【译注:中文可以说成“T类型的List”】。当你使用List时,你居然能够说出它是什么类型的List,并且你将获得强类型,编译器会为你检查它 的类型。这些只是直觉上的好处,它还有其它许多优点。当然,你并不是只能将它用于List,Hastable、Dictionary(将键影射到值上的数 据结构)——所有你想调用的都行。你可能想将String影射到Customer、将int影射到Order,在这些情况下你都能获得强类型。





















































C#泛型中的约束
Bruce Eckel:约束是如何在C#泛型中工作的呢?
Anders Hejlsberg:在C#泛型中,我们能够为类型参数施加约束。以我们的List < T > 为例,你可以说class List < T > where T : IComparable。这意味着T必须实现IComparable接口。
Bruce Eckel:有意思。在C ++ 中,约束是隐式的。
Anders Hejlsberg:是的。在C#中我们也可以这样做。譬如我们有一个Dictionary < K, V > , 它有一个Add()方法,这个方法带有K key和V value参数。Add()方法的实现将希望能够将传递进来的key和Dictionary中已经 存在的key进行比较,而且它希望使用一个称作IComparable的接口。唯一的途径就是将key参数转换为IComparable接口,然后调用 CompareTo方法。当然,当你这么做的时候,你就为K类型和key参数建立了一个隐式的约束。如果传递进来的key没有实现IComparable 接口,你会得到一个运行时错误。这在你的所有方法中都有可能出现,因为你的约定没有要求key必须实现IComparable接口。当然,你还得为运行时 类型检查付出代价,因为你实际上进行了动态类型转换。
使 用约束,你可以消除代码中的动态检查,而在编译时或装载时进行。当你要求K必须实现IComparable接口时,会发生很多事情。对于K类型的值,你现 在可以直接访问接口方法而无需类型转换。因为程序在语义上可以保证它实现了这个接口。无论什么时候你尝试建立这个类型的一个实例时,编译器都会检查这些类 型是否实现了这个接口,如果没有实现,会给你一个编译错误。如果你使用的是反射,你会得到一个异常。
Bruce Eckel:你是说编译器和运行时(都会进行检查)?
Anders Hejlsberg:编译器会检查它,但你仍有可能在运行时通过反射来做这些,因此系统还会检查它。正像我前面说的,编译时可以做的任何事都可以在运行是通过反射来做。
Bruce Eckel:我可以做一个函数模板,换句话说,一个带有不知道类型的参数的函数?你为约束添加了强类型检查,但我是不是能像C ++ 模板那样得到一个弱类型模板? 例如,我能否写一个函数,它带有两个参数A a和B b,并在代码中写a + b?我能不能说我不在乎对于A和B是否有operator + ,因为 它们是弱类型的?
Anders Hejlsberg: 你真正要问的问题应该是这在约束中如何说吧?约束,和其他特性一样,最终将可以是任意复杂的。当你考虑它的时候,约束只是一个模式匹配机制。你可能希望能 够说“这个类型参数必须有一个带有两个参数的构造器、实现了operator + 、有这个静态方法、有那两个实例方法、等等”。问题是,你希望这种模式匹配机制有多复杂?
从 没有任何东西到完全模式匹配是一个整个的连续体。没有任何东西(的模式匹配)太小了,不能说明问题;而完全模式匹配又太复杂了,因此我们需要在中间找一个 平衡点。我们允许你将约束指定为一个类、一个或多个接口,以及一些构造器约束。譬如,你可以说:“这个类型必须实现IFoo和IBar”或“这个类型必须 继承基类X”。一旦你这么做了,在编译时和运行时都会检查这个约束是否为真。这个约束所隐含的任何方法对于类型参数所指定的类型的值都是直接有效的。
现在,在C#中,运算符是静态成员。因此,运算符不能是接口的成员,因此接口约束不能带给你operator +。你只能通过类约束获得operator + ,你可以说这个类型参数必须继承自比如说Number类,并且Number类对于两个Nubmer有operator + 。但你不能抽象地说“必须有一个operator + ”,我们无法知道这句话的具体含义。
Bill Venners:你通过类型进行约束,而不是签名。
Anders Hejlsberg:是的。
Bill Venners:因此这个类型必须扩展一个类或实现一个接口。
Anders Hejlsberg:是的。而且我们还能够走得更远。实际上我们也想过再走远一些,但这会变得相当复杂。而且增加的复杂性与所得到的相比很不值得。如果你想做的事情在约束系统中不直接支持,你可以使用一个工厂模式。例如你有一个Martix < T > , 而在这个Martix(矩阵)中,你可能想定义一个“点乘”【译注:矩阵上的一种乘法运算,另一种称为“叉乘”】方法。这意味着你最终将要考虑如何将两个 T相乘,但你不能将这说成是一个约束,至少当T不是int、double或float时你不能这么说。但你可以让你的Martix带有一个 Calculator < T > 作为参数,而在Calculator < T > 中,有一个称为Multiply的方法。你可以在其中进行实现,并将结果传递给Martix。
Bruce Eckel:而且Calculator也是一个参数化的类型。
Anders Hejlsberg:是的。这有些像工厂模式,还有很多方法可以做到,这也许不是你最喜欢的方法,但做任何事情都要付出代价。
Bruce Eckel: 是呀,我开始认为C ++ 模板是一种弱类型机制。而当你想其中添加了约束后,你从弱类型走向了强类型。但这一定会带来更多的复杂性。这就是代价吧。
Anders Hejlsberg: 关于类型你可以认为它是一个轮盘。这个轮盘放得越高,程序员的日子就会越不好过,但更高的安全性随之而来。但你可以把这个轮盘向任何一个方向转得任意远。
C++ Java C#泛型的更多相关文章
- [改善Java代码]Java的泛型是类型擦除的
泛型可以减少强制类型的转换,可规范集合的元素类型,还可以提高代码的安全性和可读性,正是因为有了这些优点,自从Java引入泛型之后,项目的编码规则上便多了一条,优先使用泛型. Java泛型(Generi ...
- Java 中泛型的全面解析(转)
Java泛型(generics) 是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter).声明的类型参数在使用时用具体的类型来替换.泛型最主要的应用是在J ...
- Java中泛型 类型擦除
转自:Java中泛型是类型擦除的 Java 泛型(Generic)的引入加强了参数类型的安全性,减少了类型的转换,但有一点需要注意:Java 的泛型在编译器有效,在运行期被删除,也就是说所有泛型参数类 ...
- Java 泛型 Java使用泛型的意义
Java 泛型 Java使用泛型的意义 @author ixenos 直接意义 在编译时保证类型安全 根本意义 a) 类型安全问题源自可复用性代码的设计,泛型保证了类型安全的复用模板 b) 使用复用性 ...
- 跟着刚哥梳理java知识点——泛型(十三)
一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: public class GenericTest { public static void main(String[] a ...
- 【Java】泛型学习笔记
参考书籍 <Java核心技术:卷1> 泛型, 先睹为快 先通过一个简单的例子说明下Java中泛型的用法: 泛型的基本形式类似于模板, 通过一个类型参数T, 你可以"私人定制&qu ...
- [转] Java 的泛型擦除和运行时泛型信息获取
原文链接 https://my.oschina.net/lifany/blog/875769 前言 现在很多程序员都会在简历中写上精通 Java.但究竟怎样才算是精通 Java 呢?我觉得不仅要熟练掌 ...
- Java 容器 & 泛型:五、HashMap 和 TreeMap的自白
Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Java 容器的文章这次应该是最后一篇了:Java 容器 系列. 今天泥瓦匠聊下 Maps. 一.Ma ...
- 【译】9. Java反射——泛型
原文地址:http://tutorials.jenkov.com/java-reflection/generics.html ===================================== ...
- Java“禁止”泛型数组
Java“禁止”泛型数组 原文:https://blog.csdn.net/yi_Afly/article/details/52058708 1. 泛型定义泛型编程是一种通过参数化的方式将数据处理与数 ...
随机推荐
- HDU 4305 Lightning Matrix Tree定理
题目链接:https://vjudge.net/problem/HDU-4305 解法:首先是根据两点的距离不大于R,而且中间没有点建立一个图.之后就是求生成树计数了. Matrix-Tree定理(K ...
- IE6下面的hover不兼容
第一种解决方法: ie6中hover只是对a标签有作用 必须有href=“”,否则都不管用,如果不能写a标签,还想让ie6下有滑过效果,那只能写javascript或者jquery. 例如:ie6是不 ...
- SEO:查找网站的百度收录情况和如何让百度快速收录
查询收录的工具地址: http://tool.chinaz.com/baidu/entry/ 如何让百度快速收录: 一.大家都熟知的百度网站提交,只需要提交网站的首页即可.以前做完这一步就被百度收录的 ...
- Openstack 清除openstack网络与路由 (十七)
一)清除openstack网络与路由 “清除openstack网络与路由”和”添加openstack网络与路由”的操作步骤相反. 添加网络或路由时是先建 搭建网络>搭建子网>建立端口, 而 ...
- Maven 管理的WEB项目发布到Tomcat上
1.需要Tomcat服务器 这里可以使用已下载好的Tomcat也可以使用Maven来自动引入Tomcat插件. 通过Maven引入Tomcat服务器 在项目的pom.xml文件中project 标签中 ...
- C/C++宏的用法
今天看caffe源码的时候看到了很多宏定义的内容,苦于代码基础薄弱,无法全部理解,故在网上搜得此篇好文,转载一发附原文地址:http://blog.csdn.net/hanchaoman/articl ...
- 【转载】FloatingActionButton源码解析
原文地址:https://github.com/Rowandjj/my_awesome_blog/blob/master/fab_anlysis/README.md loatingActionButt ...
- 洛谷P4145 上帝造题的七分钟2/花神游历各国 [树状数组,并查集]
题目传送门 题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是 ...
- 洛谷——P1190 接水问题
P1190 接水问题 题目描述 学校里有一个水房,水房里一共装有 m 个龙头可供同学们打开水,每个龙头每秒钟的供水量相等,均为 1. 现在有 n 名同学准备接水,他们的初始接水顺序已经确定.将这些同学 ...
- 【大杀器】利用划分树秒杀区间内第k大的数
最近看了一道题,大概就是给出一个序列,不断询问其子区间内第k大的数,下面是个截图 绕了一圈没找到中文版题目,if(你是大佬) then 去看截图:else{我来解释:给出一个整数n,和一个整数m,分别 ...