C# 语言和公共语言运行时 (CLR) 的 2.0 版本中添加了泛型。 泛型将类型参数的概念引入 .NET Framework,这样就可以设计具有以下特征的类和方法:在客户端代码声明并初始化这些类和方法之前,这些类和方法会延迟指定一个或多个类型。
泛型定义

  泛型是为所存储或使用的一个或多个类型具有占位符(类型形参)的类、结构、接口和方法。 泛型集合类可以将类型形参用作其存储的对象类型的占位符;类型形参呈现为其字段的类型和其方法的参数类型。 泛型方法可将其类型形参用作其返回值的类型或用作其形参之一的类型。

以下代码举例说明了一个简单的泛型类定义。 

public class Generic<T>
{
public T Field;
}

创建泛型类的实例时,指定用于替代类型形参的实际类型。 在类型形参出现的每一处位置用选定的类型进行替代,这会建立一个被称为构造泛型类的新泛型类。 你将得到根据你选择的类型而定制的类型安全类,如以下代码所示。

public static void Main()
{
Generic<string> g = new Generic<string>();
g.Field = "A string";
//...
Console.WriteLine("Generic.Field = \"{0}\"", g.Field);
Console.WriteLine("Generic.Field.GetType() = {0}", g.Field.GetType().FullName);
}

例如,通过使用泛型类型参数 T,可以编写其他客户端代码能够使用的单个类,而不会产生运行时转换或装箱操作的成本或风险,如下所示:

// 定义通用泛型类
public class GenericList<T>
{
public void Add(T input) { }
}
class TestGenericList
{
private class ExampleClass { }
static void Main()
{
// 定义 int 类型的集合
GenericList<int> list1 = new GenericList<int>();
list1.Add(); // 定义 string 类型的集合
GenericList<string> list2 = new GenericList<string>();
list2.Add(""); // 定义 ExampleClass 类类型的集合
GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
list3.Add(new ExampleClass());
}
}

  泛型类和泛型方法兼具可重用性、类型安全性和效率,这是非泛型类和非泛型方法无法实现的。 泛型通常与集合以及作用于集合的方法一起使用。 .NET Framework 2.0 版类库提供新的命名空间 System.Collections.Generic,其中包含几个新的基于泛型的集合类。 建议所有定目标到 .NET Framework 2.0 及更高版本的应用程序都使用新增的泛型集合类,而不是旧的非泛型集合类(如 ArrayList)。 有关详细信息,请参阅 .NET 中的泛型

当然,也可以创建自定义泛型类型和泛型方法,以提供自己的通用解决方案,设计类型安全的高效模式。 以下代码示例演示了出于演示目的的简单泛型链接列表类。 (大多数情况下,应使用 .NET Framework 类库提供的 List<T> 类,而不是自行创建类。)在通常使用具体类型来指示列表中所存储项的类型的情况下,可使用类型参数 T。 其使用方法如下:

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

  • Node 嵌套类中作为 Data 属性的返回类型。

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

请注意,T 可用于 Node 嵌套类。 如果使用具体类型实例化 GenericList<T>(例如,作为 GenericList<int>),则出现的所有 T 都将替换为 int

// 泛型 T 类型的类
public class GenericList<T>
{
// 嵌套类也定义成泛型T类型
private class Node
{
// 泛型类型 T 作为构造函数参数
public Node(T t)
{
next = null;
data = t;
} private Node next;
public Node Next
{
get { return next; }
set { next = value; }
} // 定义一个私有 T(类型) 数据类型的变量
private T data; // T 类型作为属性的返回类型
public T Data
{
get { return data; }
set { data = value; }
}
} private Node head; // 构造函数
public GenericList()
{
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;
}
}
}

以下代码示例演示了客户端代码如何使用泛型 GenericList<T> 类来创建整数列表。 只需更改类型参数,即可轻松修改以下代码,创建字符串或任何其他自定义类型的列表:

class TestGenericList
{
static void Main()
{
// 定义 int 类型的集合
GenericList<int> list = new GenericList<int>(); for (int x = ; x < ; x++)
{
list.AddHead(x);
} foreach (int i in list)
{
System.Console.Write(i + " ");
}
System.Console.WriteLine("\n 完成");
}
}

泛型主要有两个优点:

  • 编译时可以保证类型安全。
  • 不用做类型转换,获得一定的性能提升。

泛型概述

  • 使用泛型类型可以最大限度地重用代码、保护类型安全性以及提高性能。

  • 泛型最常见的用途是创建集合类。

  • .NET Framework 类库在 System.Collections.Generic 命名空间中包含几个新的泛型集合类。 应尽可能使用这些类来代替某些类,如 System.Collections 命名空间中的 ArrayList

  • 可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。

  • 可以对泛型类进行约束以访问特定数据类型的方法。

  • 在泛型数据类型中所用类型的信息可在运行时通过使用反射来获取。

相关章节

更多相关信息:

C#2.0新增功能02 泛型的更多相关文章

  1. C#4.0新增功能02 命名实参和可选实参

    连载目录    [已更新最新开发文章,点击查看详细] C# 4 介绍命名实参和可选实参. 通过命名实参,你可以为特定形参指定实参,方法是将实参与该形参的名称关联,而不是与形参在形参列表中的位置关联.  ...

  2. C#4.0新增功能03 泛型中的协变和逆变

    连载目录    [已更新最新开发文章,点击查看详细] 协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体 ...

  3. C#5.0新增功能02 调用方信息

    连载目录    [已更新最新开发文章,点击查看详细] 通过使用调用方信息特性,可获取有关方法的调用方的信息. 可以获取源代码的文件路径.源代码中的行号和调用方的成员名称. 此信息有助于跟踪.调试和创建 ...

  4. C#3.0新增功能02 匿名类型

    连载目录    [已更新最新开发文章,点击查看详细] 匿名类型提供了一种方便的方法,可用来将一组只读属性封装到单个对象中,而无需首先显式定义一个类型. 类型名由编译器生成,并且不能在源代码级使用. 每 ...

  5. C#2.0新增功能06 协变和逆变

    连载目录    [已更新最新开发文章,点击查看详细] 在 C# 中,协变和逆变能够实现数组类型.委托类型和泛型类型参数的隐式引用转换. 协变保留分配兼容性,逆变则与之相反. 以下代码演示分配兼容性.协 ...

  6. C#基础拾遗系列之二:使用ILSpy探索C#7.0新增功能点

    C#基础拾遗系列之二:使用ILSpy探索C#7.0新增功能点   第一部分: C#是一种通用的,类型安全的,面向对象的编程语言.有如下特点: (1)面向对象:c# 是面向对象的范例的一个丰富实现, 它 ...

  7. C#基础拾遗系列之二:C#7.0新增功能点

    第一部分: C#是一种通用的,类型安全的,面向对象的编程语言.有如下特点: (1)面向对象:c# 是面向对象的范例的一个丰富实现, 它包括封装.继承和多态性.C#面向对象的行为包括: 统一的类型系统 ...

  8. C#2.0新增功能01 分布类与分部方法

    连载目录    [已更新最新开发文章,点击查看详细] 分部类型 拆分一个类.一个结构.一个接口或一个方法的定义到两个或更多的文件中, 每个源文件包含类型或方法定义的一部分,编译应用程序时将把所有部分组 ...

  9. C#7.0新增功能点

    原文地址:  https://www.cnblogs.com/runningsmallguo/p/8972678.html 第二部分:C#7.0新增的功能 (1)数字字面量的提升: C#7中的数字文字 ...

随机推荐

  1. 可视化文件消息收发一体化Socket实现V0.1

    http://blog.csdn.net/laoyang360/article/details/8681918

  2. Qt 5.3更新无数,更改C++控制台输出最为赞(这样就和普通C++ IDE没区别了)

    转载请注明文章:Qt 5.3更新无数,更改C++控制台输出最为赞 出处:多客博图 本人觉得有了这个更新,Qt Creator可谓几乎没有缺点了,起码仅仅开发C/C++,是不用再去安装VS了. Qt 5 ...

  3. Gps坐标有效性判定

    百科:纬度 是指某点与地球球心的连线和地球赤道面所成的线面角,其数值在0至90度之间.位于赤道以北的点的纬度叫北纬,记为N:位于赤道以南的点的纬度称南纬,记为S. var regex = new Re ...

  4. SYN5605型 多通道时间间隔测量仪

      SYN5605型 多通道时间间隔测量仪 时间间隔测量设备多通道时间间隔测量32路时间间隔测量仪使用说明视频链接; http://www.syn029.com/h-pd-80-0_310_6_-1. ...

  5. 微服务之服务注册与发现--Consul(转载)

    http://blog.csdn.net/buxiaoxia/article/details/69788114 https://www.cnblogs.com/xiaohanlin/p/8016803 ...

  6. NMI watchdog: BUG: soft lockup - CPU#0 stuck for 22s!

    今天测试环境一虚拟机运行中突然报错,,, 没见过的内核报错,于是google一番. 系统日志: Nov :: dev- kernel: NMI watchdog: BUG: soft lockup - ...

  7. 整理一下Apache与Tomcat的关系

    如果有对Apache与Tomcat认识比较的同学就要拿起小板凳听一下 关系一 Apache是web服务器,Tomcat是应用服务器,也就是java服务器,因为Apache只能支持静态网页,所以Apac ...

  8. JVM结构的简单梳理

    #cnblogs_post_body img { width: 500px; height: auto; } JVM是什么 JVM的基本特性 JVM的流程结构 1. Java编译(Java Compi ...

  9. 动态代理模拟实现aop

    AOP实现起来代码相当简单.主要核心是动态代理和反射. 一.接口类: public interface MethodDao { public void sayHello(); } 二.接口实现类: p ...

  10. spring springMVC Struts2 区别

    Spring: Spring是IOC和AOP的容器框架,Spring是一个通用解决方案, 最大的用处就是通过Ioc/AOP解耦, 降低软件复杂性, 所以Spring可以结合SpringMVC等很多其他 ...