所谓泛型是指将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型。
一种类型占位符,或称之为类型参数。我们知道一个方法中,一个变量的值可以作为参数,但其实这个变量的类型本身也可以作为参数。泛型允许我们在调用的时候再指定这个类型参数是什么。在.net中,泛型能够给我们带来的两个明显好处是——避免了强制类型转换,增强类型安全和减少装箱、拆箱。
通常一个方法或过程的参数都是有明确的数据类型的。
如 :
public void ProcessData(int i){}
public void ProcessData(string i){}
public void ProcessData(decimal i){}
public void ProcessData(double i){}等。
这些方法的签名中的:int ,string,decimal,double 都是明确的数据类型,我们访问这些方法的过程中需要提供提定类型的参数:
ProcessData(123);
ProcessData("abc");
ProcessData("12.12")
而如果我们将int ,string,decimal,double这些类型也当成一种参数传给方法的时候方法的定义便是这样:
public void ProcessData<T>(T i){} //T是int ,string,decimal,double这些数据类型的指代
用户在调用的时候便成了这样:
ProcessData<string>("abc");
ProcessData<int>(123);
ProcessData<double>(12.23);
这与通常的那些定义的最大区别是,方法的定义实现过程只有一个。但是它具有处理不同的数据类型数据的能力。
c#在尖括号中提供类型参数来指定泛型类,如下所示:
class Queue<T>
{
...
}
这里T就是类型参数,是作为占位符使用的,会在编译时被真正的参数类型取代。写代码实例化泛型Queue时,需要指定取代T的参数类型。在类的定义字段和方法时同样可以用占位符指定这些项的类型。
class Queue<T>
{
...
private T[] data;//T作为参数类型
...
public Queue(){
this.data =new T[DEFAULTQUEUESIZE]; //T作为数据类型
}
public void ENQueue(T item) //T作为方法参数类型
{
...
}
public T Dequeue() //T作为返回值的类型
{
...
T queueItem=this.data[this.tail]; //数组中的数据是'T'类型
...
return queueItem
}
}
虽然一般都是使用单字符T,但是参数类型T可以是任何C#的合法标识符。他会被创建Queue对象时指定的类型取代。在下面创建一个int队列和一个Horse队列:
Queue<int> intQueue=new Queue<int>();
Queue<Horse> horseQueue=new Queue<Horse>();
另外,编译器有足够的信息在生成程序时执行严格的类型检查。我们无需在调用Dequeue方法时执行强制的类型转换,能够提早发现任何类型匹配错误:
inQueue.Enqueue(99);
int myInt = intQueue.Dequeue(); //无需转型
Horse myHorse= intQueue.Dequeue(); //编译时错误
//无法将类型从Int隐式转换为Horse