zoukankan      html  css  js  c++  java
  • C#委托好处知多少

    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的运行时间远远大于代码片段的运行时间。

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

    首先,你应该能看出,代码片段1与代码片段2的功能完全等价,都是将110000000之间的整数循环添加进集合(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语言中使用。

    就总结到这里了。

  • 相关阅读:
    winform 单选框, 图像控件,图像列表,状态栏,定时器,绘图
    学习资料链接,csdn博客
    c# 基本控件,窗口程序
    Gmap.net 怎么导入离线地图
    修改MFC主窗口界面标题和图标的方法
    vc6.0缓冲区
    vc6.0编译出错,删除多余的文件,清空重新编译
    Tomcat插件与Jetty插件在MyEclipse中的配置
    div里面的内容超出自身高度时,显示省略号
    aptana studio 3 自动换行(无需插件)
  • 原文地址:https://www.cnblogs.com/james1207/p/3295347.html
Copyright © 2011-2022 走看看