推迟一切可以推迟的东西

时间:2022-01-04 00:41:44

标签:

泛型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性。泛型为.NET框架引入了类型参数(type parameters)的概念。类型参数使得设计类和方法时,不必确定一个或多个具体参数,其的具体参数可延迟到客户代码中声明、实现。这意味着使用泛型的类型参数T,写一个类MyList<T>,客户代码可以这样调用:MyList<int>MyList<string>MyList<MyClass>。这避免了运行时类型转换或装箱操作的代价和风险。

泛型是利用延迟加载思想,延迟声明,不是语法糖

泛型方法性能==普通方法>Object方法(需要装箱拆箱)

即时编译器,中间语言IL转成JIT(机器码) 生成一个占位符`1,MetaData

目录

C# 中的泛型. 1

一、泛型概述. 2

二、泛型的优点. 5

三、泛型类型参数. 7

四、类型参数的约束. 8

五、泛型类. 11

六、泛型接口. 13

七、泛型方法. 19

八、泛型委托. 21

九、泛型代码中的default 关键字. 23

十、C++ 模板和C# 泛型的区别. 24

十一 、运行时中的泛型. 25

十二 、基础类库中的泛型. 27

一、泛型概述

泛型类和泛型方法兼复用性、类型安全和高效率于一身,是与之对应的非泛型的类和方法所不及。泛型广泛用于容器(collections)和对容器操作的方法中。.NET框架2.0的类库提供一个新的命名空间System.Collections.Generic,其中包含了一些新的基于泛型的容器类。要查找新的泛型容器类(collection classes)的示例代码,请参见基础类库中的泛型。当然,你也可以创建自己的泛型类和方法,以提供你自己的泛化的方案和设计模式,这是类型安全且高效的。下面的示例代码以一个简单的泛型链表类作为示范。(多数情况下,推荐使用由.NET框架类库提供的List<T>类,而不是创建自己的表。)类型参数T在多处使用,具体类型通常在这些地方来指明表中元素的类型。类型参数T有以下几种用法:

l        AddHead方法中,作为方法参数的类型。

l        在公共方法GetNext中,以及嵌套类NodeData属性中作为返回值的类型。

l        在嵌套类中,作为私有成员data的类型。

注意一点,T对嵌套的类Node也是有效的。当用一个具体类来实现MyList<T>——MyList<int>——每个出现过的T都要用int代替。

using System; using System.Collections.Generic;   public class MyList<T> //角括号中的类型参数     {         private Node head; // 嵌套类型也是一般的T         private class Node                   {             private Node next; //T 作为私有成员数据类型:             private T data;          //T 非泛型构造函数中:             public Node(T t)                     {                 next = null;                 data = t;             }             public Node Next             {                 get { return next; }                 set { next = value; }             } //T 作为返回类型的属性:             public T Data                        {                 get { return data; }                 set { data = value; }             }         }         public MyList()         {             head = null;         } //T 作为方法参数类型:         public void AddHead(T t)             {             Node n = new Node(t);             n.Next = head;             head = n;         }           public IEnumerator<T> GetEnumerator()         {             Node current = head;               while (current != null)             {                 yield return current.Data;                 current = current.Next;             }         }     }