zoukankan      html  css  js  c++  java
  • 泛型的优点

    1.前言

    泛型(Generic)的优点主要体现在提升性能和类型安全两方面,下面将对这两点进行分析。

    2.提升性能

    通过编写一个使用 .NET 类库中 ArrayList 集合类的小程序,可体现出使用非泛型集合类的局限。 ArrayList 类的实例可以存储任何引用或值类型。

    System.Collections.ArrayList list1 = new System.Collections.ArrayList();
    list1.Add(3);
    list1.Add(105);
    
    System.Collections.ArrayList list2 = new System.Collections.ArrayList();
    list2.Add("It is raining in Redmond.");
    list2.Add("It is snowing in the mountains.");
    View Code

    但这种便利有一定代价。 添加到 ArrayList 的任何引用或值类型均隐式向上转换为 Object。 如果项为值类型,将它们添加到列表时必须将其装箱,检索它们时必须取消装箱。 转换与装箱/取消装箱这两种操作都会降低性能;在必须循环访问大型集合的方案中,装箱与取消装箱的影响非常大。

    下面创建一个的示例,查看两者的 IL 代码,示例代码如下:

    class Test
    {
        static void ArrayDemo()
        {
            ArrayList arrayList = new ArrayList();
            arrayList.Add(12);
            Console.WriteLine(arrayList[0]);
        }
        static void GenericDemo()
        {
            List<int> list = new List<int>();
            list.Add(12);
            Console.WriteLine(list[0]);
        }
        static void Main()
        {
            ArrayDemo();
            GenericDemo();
        }
    }
    View Code

    ArrayList 类型的 IL 代码如下:

    .method private hidebysig static void  ArrayDemo() cil managed
    {
      // Code size       35 (0x23)
      .maxstack  2
      .locals init ([0] class [mscorlib]System.Collections.ArrayList arrayList)
      IL_0000:  nop
      IL_0001:  newobj     instance void [mscorlib]System.Collections.ArrayList::.ctor()
      IL_0006:  stloc.0
      IL_0007:  ldloc.0
      IL_0008:  ldc.i4.s   12
      IL_000a:  box        [mscorlib]System.Int32
      IL_000f:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)
      IL_0014:  pop
      IL_0015:  ldloc.0
      IL_0016:  ldc.i4.0
      IL_0017:  callvirt   instance object [mscorlib]System.Collections.ArrayList::get_Item(int32)
      IL_001c:  call       void [mscorlib]System.Console::WriteLine(object)
      IL_0021:  nop
      IL_0022:  ret
    } // end of method Test::ArrayDemo
    View Code

    泛型 List<int> 的 IL 代码如下:

    .method private hidebysig static void  GenericDemo() cil managed
    {
      // Code size       30 (0x1e)
      .maxstack  2
      .locals init ([0] class [mscorlib]System.Collections.Generic.List`1<int32> list)
      IL_0000:  nop
      IL_0001:  newobj     instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
      IL_0006:  stloc.0
      IL_0007:  ldloc.0
      IL_0008:  ldc.i4.s   12
      IL_000a:  callvirt   instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
      IL_000f:  nop
      IL_0010:  ldloc.0
      IL_0011:  ldc.i4.0
      IL_0012:  callvirt   instance !0 class [mscorlib]System.Collections.Generic.List`1<int32>::get_Item(int32)
      IL_0017:  call       void [mscorlib]System.Console::WriteLine(int32)
      IL_001c:  nop
      IL_001d:  ret
    } // end of method Test::GenericDemo
    View Code

    可以比较看出,通过创建泛型类型可以减少拆箱装箱的操作,从而提高性能。

    3.类型安全

    另一局限是缺少编译时类型检查;由于 ArrayList 将所有内容都转换为 Object,因此在编译时无法阻止客户端代码执行如下操作:

    System.Collections.ArrayList list = new System.Collections.ArrayList();
    // Add an integer to the list.
    list.Add(3);
    // Add a string to the list. This will compile, but may cause an error later.
    list.Add("It is raining in Redmond.");
    
    int t = 0;
    // This causes an InvalidCastException to be returned.
    foreach (int x in list)
    {
        t += x;
    }
    View Code

    虽然在创建异类集合时这完全可以接受,甚至有时是有意为之,但将字符串和 ints 合并到单个 ArrayList 中更有可能属于编程错误,且此错误在运行时之前不会被检测出。

    而在使用泛型类型的时候会使用占位符 <T> 为其指定类型,在创建实例后保证其类型安全。

  • 相关阅读:
    写一个函数的程序,判断是否是浮点数
    写一个函数,输入一个数,随机生成N条邮箱
    day4-python基础知识 <元组&&集合>
    day4-python基础知识<文件操作>
    程序--用户登录--<while循环>
    程序--<猜数字小游戏>--for
    使用ajax后提交事件后禁用按钮,事件执行完毕后,重新启用按钮
    ajax在弹出对话框中实现一个UpdateProgress进度条控件源代码
    运算符的结合性
    匿名方法
  • 原文地址:https://www.cnblogs.com/jizhiqiliao/p/9842997.html
Copyright © 2011-2022 走看看