目录
一. 概述:
所谓泛型即广泛的类型,也就是在书写代码时不指定具体类型,等到执行时候在指定。C#项目要先编译成中间语言(MSIL),在通过JIT编译成机器语言执行。使用泛型就是在编译成中间语言的时候先占一个坑,等到JIT的时候在根据实际运行情况决定具体类型。
就拿装修来说,准备装修电视墙方案的时候,不确定到底是放电视还是投影布。为了不影响整体方案进度,我们就可以用一个矩形框占个坑,等到实际装修的时候,不管是电视,还是投影布放到坑上就好了。
这个坑就是我们的泛型
二. 泛型举例
List<T> 是 System.Collections.Generic 命名空间下的一个类,其中T就是泛型,源码如下图:
使用的时候才指定T 的类型,代码如下:
// Lis<T> 就是一个泛型类
List<int> intList = new List<int>();
intList.Add(1);
intList.Add(2);
intList.Add(3);
List<string> stringList = new List<string>();
stringList.Add("A");
stringList.Add("B");
stringList.Add("C");
其中 intList 中 指定T是int 类型,所以后面Add()方法只能添加int类型值;stringList 指定 T是string类型,所以后面Add()方法只能添加string 类型的值。
三. 泛型好处
上面的例子显而易见,如果没有泛型,那么List将会演变成两个不同的类(一个专门生成int类型List 的类和一个专门生成string类型List的类),仅仅是因为类型不一样。C#类型众多,且不是要为每个类型写一个List专用类型。所以,泛型提高代码重用。当然网上很多用List<T>和ArrayList进行比较得出泛型有性能优势,我不敢沟通,我觉得只能说明List<T>在性能上比ArrayList有优势,并不能说明泛型具有性能优势。
四.泛型使用
目前泛型只能运用到方法,类,接口,委托,下面一一介绍:
1. 泛型方法 :一个方法满足多个类型需求
2. 泛型类 :一个类 满足多个类型的需求
3. 泛型接口 :一个接口 满足多个多个类型的需求
4. 泛型委托 :一个委托 满足多个多个类型的需求
五.泛型约束
1 | T:struct | 参数必须是值类型 |
2 | T:class | 参数必须是引用类型 |
3 | T:new() | 参数必须具有无参的公共构造函数,若和其它约束一起用,new()约束必须最后指定 |
4 | T:<基类名> | 类型参数必须是指定的基类或派生自指定的基类 |
5 | T:<接口名称> | 类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。 |
6 |
六.泛型约束好处
回到装修留个矩形框在电视墙上作为泛型,但是这个矩形框不是随便留的,它的位置,大小我们要确定好,这样不会影响整体美观,这就是约束,举个C#的例子如下:
public class baseClass
{
public int Id { get; set; }
}
public class ChildClass : baseClass
{
//other
}
public class GenericTest
{
public void testGeneric()
{ //调用Test<T>方法
test<ChildClass>(new ChildClass()); //该处T只能是继承 baseClass 的对象否则报错
//test<int>(1);//报错
}
public void test<T>(T t)
where T : baseClass
{
int Id = t.Id;//可以直接访问基类Id
}
}
上述指定T类型必须继承 baseClass,否则报错,
说的直白的一点,我提供的这个泛型方法只能处理基于baseClass的对象,其它类型处理不了。我之所以约束你,是怕你不小心传入了错误的参数。同样,我知道的我T是继承于baseClass的对象,所以,baseClass中的所有公开属性&方法是可以直接用。
七.总结
以上就是对泛型的理解,其实就一句话,先给你占个坑,用的时候在来告诉我类型,往往泛型要和反射同时使用,下一章介绍反射相关概念