日期:2009-01-26  浏览次数:20501 次

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









目录

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中,以及嵌套类Node的 Data属性中作为返回值的类型。

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



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



using System;

using System.Collections.Generic;



public class MyList<T> //type parameter T in angle brackets

{

private Node head;

// The nested type is also generic on T.

private class Node

{

private Node next;

//T as private member data type:

private T data;

//T used in non-generic constructor:

public Node(T t)

{

next = null;

data = t;

}

public Node Next

{

get { return next; }

set { next = value; }

}

//T as return type of property:

public T Data

{

get { return data; }

set { data = value; }

}

}

public MyList()

{

head = null;

}

//T as method parameter type:

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;

}

}

}



下面的示例代码演示了客户代码如何使用泛型类MyList<T>,来创建一个整数表。通过简单地改变参数的类型,很容易改写下面的代码,以创建字符串或其他自定义类型的表。



class Program

{

static void Main(string[] args)

{

//int is the type argument.

MyList<int> list = new MyList<int>();

for (int x = 0; x < 10; x++)

list.AddHead(x);



foreach (int i in list)

{

Console.WriteLine(i);

}