一、什么是泛型
泛型是C#2.0推出的新语法,不是语法糖,而是2.0由框架升级提供的功能。
我们在编程程序时,经常会遇到功能非常相似的模块,只是它们处理的数据不一样。但我们没有办法,只能分别写多个方法来处理不同的数据类型。这个时候,那么问题来了,有没有一种办法,用同一个方法来处理传入不同种类型参数的办法呢?泛型的出现就是专门来解决这个问题的。
二、为什么使用泛型
先来看下面一个例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyGeneric
{
public class CommonMethod
{
///
/// 打印个int值
///
/// 因为方法声明的时候,写死了参数类型
/// 已婚的男人 Eleven San
///
///
public static void ShowInt(int iParameter)
{
Console.WriteLine("This is {0},parameter={1},type={2}",
typeof(CommonMethod).Name, iParameter.GetType().Name, iParameter);
}
///
/// 打印个string值
///
///
public static void ShowString(string sParameter)
{
Console.WriteLine("This is {0},parameter={1},type={2}",
typeof(CommonMethod).Name, sParameter.GetType().Name, sParameter);
}
///
/// 打印个DateTime值
///
///
public static void ShowDateTime(DateTime dtParameter)
{
Console.WriteLine("This is {0},parameter={1},type={2}",
typeof(CommonMethod).Name, dtParameter.GetType().Name, dtParameter);
}
}
}
从上面的结果中我们可以看出这三个方法,除了传入的参数不同外,其里面实现的功能都是一样的。在1.0版的时候,还没有泛型这个概念,那么怎么办呢。相信很多人会想到了OOP三大特性之一的继承,我们知道,C#语言中,object是所有类型的基类,将上面的代码进行以下优化:
public static void ShowObject(object oParameter)
{
Console.WriteLine("This is {0},parameter={1},type={2}", typeof(CommonMethod), oParameter.GetType().Name, oParameter);
}
从上面的结果中我们可以看出,使用Object类型达到了我们的要求,解决了代码的可复用。可能有人会问定义的是object类型的,为什么可以传入int、string等类型呢?原因有二:
1、object类型是一切类型的父类。
2、通过继承,子类拥有父类的一切属性和行为,任何父类出现的地方,都可以用子类来代替。
但是上面object类型的方法又会带来另外一个问题:装箱和拆箱,会损耗程序的性能。
微软在C#2.0的时候推出了泛型,可以很好的解决上面的问题。
三、泛型类型参数
在泛型类型或方法定义中,类型参数是在其实例化泛型类型的一个变量时,客户端指定的特定类型的占位符。 泛型类( GenericList
)无法按原样使用,因为它不是真正的类型;它更像是类型的蓝图。 若要使用 GenericList
,客户端代码必须通过指定尖括号内的类型参数来声明并实例化构造类型。 此特定类的类型参数可以是编译器可识别的任何类型。 可创建任意数量的构造类型实例,其中每个使用不同的类型参数。
namespace MyGeneric
{
public class GenericMethod
{
///
/// 泛型方法
///
///
///
public static void Show
{
Console.WriteLine("This is {0},parameter={1},type={2}",
typeof(GenericMethod), tParameter.GetType().Name, tParameter.ToString());
}
}
}
为什么泛型可以解决上面的问题呢?
泛型是延迟声明的:即定义的时候没有指定具体的参数类型,把参数类型的声明推迟到了调用的时候才指定参数类型。 延迟思想在程序架构设计的时候很受欢迎。例如:分布式缓存队列、EF的延迟加载等等。
泛型究竟是如何工作的呢?
控制台程序最终会编译成一个exe程序,exe被点击的时候,会经过JIT(即时编译器)的编译,最终生成二进制代码,才能被计算机执行。泛型加入到语法以后,VS自带的编译器又做了升级,升级之后编译时遇到泛型,会做特殊的处理:生成占位符。再次经过JIT编译的时候,会把上面编译生成的占位符替换成具体的数据类型。
泛型方法的性能最高,其次是普通方法,object方法的性能最低。
四、泛型类
除了方法可以是泛型以外,类也可以是泛型的;
除了可以有泛型类,也可以有泛型接口;
注意:
1、泛型在声明的时候可以不指定具体的类型,但是在使用的时候必须指定具体类型,如果子类也是泛型的,那么继承的时候可以不指定具体类型
五、什么是泛型集合?
字符串可以说是一个字符的集合,和字符串一样,数据对象也可以是集合的方式存在,所以泛型类对象也可以是集合的方式存在(泛型集合)
同传统的集合相比,泛型集合是一种强类型的集合,它解决了类型安全问题,同时避免了集合中每次的装箱与拆箱的操作,提升了性能。
泛型集合类型:
1. List,这是我们应用最多的泛型种类,它对应ArrayList集合。
2. Dictionary,这也是我们平时运用比较多的泛型种类,对应Hashtable集合。
3. Collection对应于CollectionBase
4. ReadOnlyCollection 对应于ReadOnlyCollectionBase,这是一个只读的集合。
5. Queue,Stack和SortedList,它们分别对应于与它们同名的非泛型类。