呼~今天开始高级特性的连载,那么第一篇,就是我们最熟悉,最常见的泛型。什么?你不知道什么是泛型?那好吧,List<>这个总见过吧,这就是泛型!
接下来,我们通过这么一个案例,来了解一下,泛型为什么出现,泛型在哪里应用。
一、为什么要使用泛型?
泛型的出现,是为了实现一个类型满足多个类型的需求。
1、案例讲解
首先,建立一个公共方法类,有三个方法,传入参数分别树int,string,datetime
public class CommonMethod
{
public void ShowInt(int iParameter)
{
Console.WriteLine("传入的是:"+iParameter+"类型是:"+iParameter.GetType());
}
public void ShowString(string sParameter)
{
Console.WriteLine("传入的是:" + sParameter + "类型是:" + sParameter.GetType());
}
public void ShowDatetime(DateTime dtParameter)
{
Console.WriteLine("传入的是:" + dtParameter + "类型是:" + dtParameter.GetType());
}
}
复制代码
其次,当我们在主程序调用时,需要传入不同的参数,来调用方法。
那么,问题就来了,我们发现,这几个方法只有参数不同,我能不能改进呢? 当然有,在以前我们使用object来设定参数,因为 object是一切类型的父类,并且任何父类出现的地方都可以用其子类代替。 public void ShowDatetime(object oParameter)
{
Console.WriteLine("传入的是:" + oParameter + "类型是:" + oParameter.GetType());
}
复制代码
但是,为什么我们现在不用呢,而用泛型呢,是由原因的。
object的缺点
- 1、装箱拆箱,性能损耗。
装箱:当传入一个int值时,在栈上,object又在堆上,就会把int值copy到堆里;
拆箱:当使用int值时,又copy到栈里 - 2、类型安全问题,传递的对象是没有限制的。
那么,微软为了解决这种问题,出现了泛型,不会有性能损耗,也不会有传入对象不安全的问题。
泛型方法的创建和调用
创建:public void ShowT<T>(T t)
- 1、方法名称后尖括号,里面时类型参数
- 2、类型参数实际上就是一个类型T声明,方法就可以使用这个类型T了
调用:commonMethod.Show<int>(iParameter)
- 1、调用泛型,需要指定类型参数
- 2、如果可以从参数推断类型,可以省略类型参数commonMethod.Show(1)
public void ShowT<T>(T tParameter)
{
Console.WriteLine("传入的是:" + tParameter + "类型是:" + tParameter.GetType());
}
复制代码
这样,就解决了,一个类型满足多种不同类型的需求
二、泛型为什么,也可以支持多种不同类型的参数?
在以前,声明方法时,指定了参数类型,确定了只能传递那个类型。
- 泛型声明方法时,并没有写死类型,T是什么,不知道;
- T要等调用的时候才知道;
- 正是因为没有写死,才有无限可能;
- 设计思想--延迟加载:推迟一切可以推迟的,一切可以晚点做的事晚点做;
三、泛型的运行原理
泛型在编译时,使用的占位符,在调用运行时指定了类型。
C#的编译机制: C#高级语言-编译器-Dll/Exe-IL-CLR-机器码(0101)
在编译器,编译时使用了占位符,调用运行时指定了类型,转换成dll/exe,通过中间语言IL转换成汇编语言CLR,在转换成机器码
四、泛型在哪里应用?
其实,写了这么多代码。当我们发现一些代码,只有参数啊,返回值不同时,其他操作都一样时,我们就该考虑泛型了。
上面都是个人理解,不足的地方,希望批评指正