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> 为其指定类型,在创建实例后保证其类型安全。

  • 相关阅读:
    485串口接线
    mvc3 升级mvc5
    VB连接ACCESS数据库,使用 LIKE 通配符问题
    VB6 读写西门子PLC
    可用的 .net core 支持 RSA 私钥加密工具类
    解决 Win7 远程桌面 已停止工作的问题
    解决 WinForm 重写 CreateParams 隐藏窗口以后的显示问题
    解决安装 .net framework 发生 extracting files error 问题
    CentOS7 安装配置笔记
    通过特殊处理 Resize 事件解决 WinForm 加载时闪烁问题的一个方法
  • 原文地址:https://www.cnblogs.com/jizhiqiliao/p/9842997.html
Copyright © 2011-2022 走看看