泛型类型概述

开发人员在 .NET 中一直使用泛型,无论是隐式还是显式。 在 .NET 中使用 LINQ 时,你是否曾经注意到,使用的正是 IEnumerable<T>? 或者,如果曾经看到使用 Entity Framework 与数据库通信的“泛型存储库”联机示例,你是否看到大多数方法返回 IQueryable<T>? 你可能想知道这些示例中的 T 是什么,为什么它在那里。

泛型最初在 .NET Framework 2.0 中引入,实质上是一个“代码模板”,开发人员无需提交实际数据类型即可定义 类型安全的 数据结构。 例如,是一个List<T>可以声明并用于任何类型,例如List<int>List<string>List<Person>

为了了解泛型为何有用,让我们来看看添加泛型之前和之后的特定类: ArrayList 在 .NET Framework 1.0 中, ArrayList 元素的类型 Object为 。 添加到集合的任何元素都以无提示方式转换为一个 Object。 从列表中读取元素时也会出现相同的情况。 此过程称为 装箱和取消装箱,会影响性能。 但是,除了性能之外,在编译时无法确定列表中的数据类型,这会使某些代码变得脆弱。 泛型通过定义列表的每个实例将包含的数据类型来解决此问题。 例如,只能向List<int>添加整数,并且只能将人员添加到List<Person>

泛型还可以在运行时使用。 运行时知道所使用的数据结构类型,并且可以更有效地将其存储在内存中。

以下示例是一个小程序,演示了在运行时了解数据结构类型的效率:

  using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Diagnostics;

  namespace GenericsExample {
    class Program {
      static void Main(string[] args) {
        //generic list
        List<int> ListGeneric = new List<int> { 5, 9, 1, 4 };
        //non-generic list
        ArrayList ListNonGeneric = new ArrayList { 5, 9, 1, 4 };
        // timer for generic list sort
        Stopwatch s = Stopwatch.StartNew();
        ListGeneric.Sort();
        s.Stop();
        Console.WriteLine($"Generic Sort: {ListGeneric}  \n Time taken: {s.Elapsed.TotalMilliseconds}ms");

        //timer for non-generic list sort
        Stopwatch s2 = Stopwatch.StartNew();
        ListNonGeneric.Sort();
        s2.Stop();
        Console.WriteLine($"Non-Generic Sort: {ListNonGeneric}  \n Time taken: {s2.Elapsed.TotalMilliseconds}ms");
        Console.ReadLine();
      }
    }
  }

此程序生成类似于以下内容的输出:

Generic Sort: System.Collections.Generic.List`1[System.Int32]
 Time taken: 0.0034ms
Non-Generic Sort: System.Collections.ArrayList
 Time taken: 0.2592ms

此处可以注意到的第一件事是,对泛型列表进行排序比对非泛型列表进行排序要快得多。 你可能还会注意到泛型列表的类型是不同的([System.Int32]),而非泛型列表的类型是通用的。 由于运行时知道泛型 List<int> 的类型是 Int32,因此它可以将列表元素存储在内存中的一个基础整数数组中,而非泛型 ArrayList 则必须将每个列表元素转换为对象类型。 如本示例中所示,多余的强制转换会占用时间,降低列表排序的速度。

运行时了解泛型类型的另一个优势是更好的调试体验。 在 C# 中调试泛型时,你知道每个元素在数据结构中的类型。 如果没有泛型,则不知道每个元素的类型。

另请参阅