1.性能

性能是泛型的一个主要优点。

直接上例子,通过实例可以让我们很好的理解这一点。

Stopwatch stopwatch = new Stopwatch();
stopwatch.Start(); //开始监视 //-----代码片段1------------------Start
ArrayList al = new ArrayList();
for (int i = 1; i <= 10000000; i++)
{
al.Add(i);
}
foreach (int i in al)
{
//do what you want
int j = i + 1;
}
//-----代码片段1------------------End stopwatch.Stop(); //停止监视
TimeSpan timespan = stopwatch.Elapsed; //获取代码运行时间
Console.WriteLine("代码片段1执行时间为:" + timespan.ToString()); Stopwatch stopwatch1 = new Stopwatch();
stopwatch1.Start(); //开始监视 //-----代码片段2------------------start
List<int> il = new List<int>();
for (int i = 1; i <= 10000000; i++)
{
il.Add(i);
}
foreach (int i in il)
{
//do what you want
int j = i + 1;
}
//-----代码片段2------------------end stopwatch1.Stop(); //停止监视
TimeSpan timespan1 = stopwatch1.Elapsed; //获取代码运行时间
Console.WriteLine("代码片段2执行时间为:" + timespan1.ToString());

代码运行结果为:

很显然,代码片段1的运行时间远远大于代码片段2 的运行时间。

下面将详细地说明一下代码片段1及代码片断2都干了些什么,以及是什么造成了两段代码运行时间的巨大差距。

首先,你应该能看出,代码片段1与代码片段2的功能完全等价,都是将1到10000000之间的整数循环添加进集合(ArrayList或List<T>),再从集合中循环取出这10000000个整数,做你想做的处理(想做就做呗,呵呵)。

既然功能一样,那么性能为什么会有如此之大的区别呢。

因为代码片段1中,ArrayList存储对象时,Add()方法被定义为接受一个对象(object)作为参数(见图* ArrayList Add()方法签名),所以使用Add()方法接受一个整型数据时,需要进行装箱操作。在读取ArrayList中的元素时,要进行拆箱,把对象转换成整型类型。

图* ArrayList Add()方法签名

可见,装箱与拆箱的实现并不难,但是性能损失较大。

当循环迭代次数很多时,性能损耗尤其明显。对于这一点,我们可以做个简单的实验,将实例的循环次数改为1000,得到以下结果:

结果显示:这种情况下,代码片段1的执行时间约为代码片段2执行时间的两倍。而循环次数为10000000时,代码片段1的执行时间约为代码片段2执行时间的四倍。

最后,将循环次数设置为1,此时运行结果为:

这种情况下,代码片段1的执行时间仍约为代码片段2执行时间的两倍(其实是1.9倍,倍数是减少了点,不过跟循环1000次区别不大)。

对于这一点就不赘述了,只要有这种印象就行了。

代码片段2中,List<T>类不使用对象,而是在使用时定义类型。在本实例中,泛型类型被定义为int,所以代码片段2中相关操作均会使用int类型(见图** List<int>类 Add()方法签名),不管是循环添加数据还是循环读取数据,都将使用int类型,所以不存在装箱与拆箱操作。

图** List<int>类 Add()方法签名

到这里,我们已经可以很好的理解:性能是泛型的主要优点。

2.类型安全

聊完了性能,来聊聊泛型的另一个优点,类型安全。

在介绍类型安全时,我们还是会使用ArrayList与List<T>作为演示对象。

//-----代码片段3------------------Start
ArrayList al = new ArrayList();
al.Add(1);
//下面的代码编译没问题,但是运行时会报错
al.Add("tiana0");
foreach (int i in al)
{
//do what you want
}
//-----代码片段3------------------End //-----代码片段4------------------start
List<int> il = new List<int>();
il.Add(1);
//下面的代码编译器会提示与“System.Collections.Generic.List<int>.Add(int)”最匹配的重载方法具有一些无效参数
//编译就无法通过
il.Add("tiana0");
foreach (int i in il)
{
//do what you want
}
//-----代码片段4------------------end

代码片段3,能够正常编译,但是执行时会报错,错误信息如下:

提示“制定的转换无效”。

分析代码,我们很容易定位异常代码位置:foreach (int i in al),因为在前面我们给ArrayList添加了字符串元素“tiana0”,而该元素是不可能转换成整型数据的,导致程序无法执行而出现一个运行异常。

对于代码片段4,错误在编译时就被及时的发现了。因为有了List<T>的定义,就只能把整型数据添加到集合中,将字符串添加到集合时会导致编译错误,提示与“System.Collections.Generic.List<int>.Add(int)”最匹配的重载方法具有一些无效参数。

所以,使用泛型时,编译器可以执行更多地检查,确保类型安全。

而在使用ArrayList时,你可以向集合中添加任何元素,可以是整型数据,可以是字符串,还可以是自定义类型数据,无法确保类型安全。

到这里,我们得出结论:类型安全是泛型的另一特点。

3.二进制代码重用

这个较好理解,泛型类型可以在一种语言中定义,在另一种.Net语言中使用。

就总结到这里了。

C#委托好处知多少的更多相关文章

  1. C#_基础

    1.形参与实参 形参是函数定义时的参数,实参是函数被引用时传给它的参数 2.重载与重写 重载:发生在同一个类中,函数(方法)名相同但参数列表必须不同,返回类型可以不同 重写:发生在继承类之间,子类必须 ...

  2. js-事件、正则表达式

    AddEventListener()之中有三个参数,分别是(1)事件的名称(注:不要加on,例:click才是点击事件的名称)(2)需要执行的function(){} (3)布尔类型(false表示的 ...

  3. Spring IOC知识点一网打尽!

    前言 只有光头才能变强 回顾前面: 给女朋友讲解什么是代理模式 包装模式就是这么简单啦 单例模式你会几种写法? 工厂模式理解了没有? 在刷Spring书籍的时候花了点时间去学习了单例模式和工厂模式,总 ...

  4. json 拖拽

    1.梳理知识点 1.事件对象   e || event  2.事件对象的属性      鼠标事件对象 : 坐标属性 :  clientX  clientY  pageX  pageY   offset ...

  5. 重学 Java 设计模式:实战工厂方法模式

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获!

  6. 安装Archlinux+UEFI启动

    为了安装Arch自己也走了很多弯路,找了很多教程,最后探索出了这样一个安装方法,不一定适用于每个人. ArchWiki官方安装手册 本方法全程插上网线. 准备 获取镜像 镜像可以从官网获取,访问官方下 ...

  7. vue—你必须知道的 js数据类型 前端学习 CSS 居中 事件委托和this 让js调试更简单—console AMD && CMD 模式识别课程笔记(一) web攻击 web安全之XSS JSONP && CORS css 定位 react小结

    vue—你必须知道的   目录 更多总结 猛戳这里 属性与方法 语法 计算属性 特殊属性 vue 样式绑定 vue事件处理器 表单控件绑定 父子组件通信 过渡效果 vue经验总结 javascript ...

  8. 聊一聊JQ中delegate事件委托的好处

    下面举个例子 我们希望通过点击使得点击的li标签变红 <body style="height:2000px;"> <ul> <li>1111&l ...

  9. .net 委托的使用方法以及使用委托的好处

    使用方法: //无返回值无参数委托的定义方法 public delegate void NoReturnPara(); 给委托赋值的几种方式 //实例化委托,并传入方法 NoReturbNoPara ...

随机推荐

  1. 帝国cms7.0忘记后台管理账户用户名密码

    最近刚登陆以前的网站,但是发现自己的后台管理用户名密码已经忘记,于是到帝国cms论坛里面找了一下解决方案,成功解决问题.特此分享一下解决成功经验. 原帖地址:http://bbs.phome.net/ ...

  2. 禁用Java DNS缓存-Disable DNS caching

    Once an application has performed network access (i.e. urlconnection, parsing of xml document with e ...

  3. Spring Boot 属性配置和使用

    Spring Boot 属性配置和使用 Spring Boot 允许通过外部配置让你在不同的环境使用同一应用程序的代码,简单说就是可以通过配置文件来注入属性或者修改默认的配置. Spring Boot ...

  4. linux内核源码阅读之facebook硬盘加速利器flashcache

    从来没有写过源码阅读,这种感觉越来越强烈,虽然劣于文笔,但还是下定决心认真写一回. 源代码下载请参见上一篇flashcache之我见 http://blog.csdn.net/liumangxiong ...

  5. UVA 12230 - Crossing Rivers(概率)

    UVA 12230 - Crossing Rivers 题目链接 题意:给定几条河,每条河上有来回开的船,某一天出门,船位置随机,如今要求从A到B,所须要的期望时间 思路:每条河的期望,最坏就是船刚开 ...

  6. js动画学习(三)

    五.多物体变宽 这里面要注意由于物体变多了,需要给每个物体各配备一个定时器,否则如果只有一个定时器的话,当鼠标在不同物体之间快速滑动时,不同的物体就会出现争抢的现象.所以timer前要加obj. fu ...

  7. nodejs partials 分布视图

    在学习<node.js开发指南>nodejs partials view时,怎么都不能运行成功.经过艰苦探索,终于成功了,分享一下. Cause: nodejs 的express 版本之间 ...

  8. Xcode之外的文档浏览工具--Dash (在iOS代码库中浏览本帖)

    链接地址:http://www.cocoachina.com/bbs/read.php?tid=273479 Xcode之外的文档浏览工具--Dash    (在iOS代码库中浏览本帖)       ...

  9. 杭电ACM 2052 Picture

    Picture Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  10. SDWebImage 常用方法

    SDWebImage是iOS中一款处理图片的框架, 使用它提供的方法, 一句话就能让UIImageView自动去加载并显示网络图片.特别是在UITableViewCell中有UIImageView需要 ...