写在前面:此随笔仅仅是做为我的学习总结,有不对的地方,请各位前辈指正O(∩_∩)O........程序员
一: 什么是泛型c#
泛型是c#2.0以后新特性,是一种语法糖.将大量的安全检查从执行期转移至了编译期,使类型参数化.大至思想就是编译时期肯定其类型,延迟思想.安全
二: 使用泛型架构
1: 泛型的出现,提升了性能,那么没有泛型以前是一个什么样子呢?函数
举个例子:性能
好比,咱们要分别输出一个数字和字符串,咱们须要像这样写:学习
/// <summary> /// 打印数字 /// </summary> /// <param name="i"></param> public void PrintInt(int i) { Console.WriteLine("this is a method print number: {0},this type is {1}", i, i.GetType()); } /// <summary> /// 打印字符串 /// </summary> /// <param name="s"></param> public void PrintString(string s) { Console.WriteLine("this is a method print string: {0},this type is {1}",s,s.GetType()); }
能够看到上面两个方法内部都是基本上相同的.那聪明的程序员们就思考怎么能够优化上面的代码.咱们能够知道object是全部的父类,那么就有了下面这一个优化以后的代码:优化
public void PrintObject(object o) { Console.WriteLine("this is a method print object: {0},this type is {1}", o,o.GetType()); }
这样咱们就把两个方法优化成了一个方法,达到了同样的目的.接下来问题又来了,如今这样的写法,就又存在了一个问题,就是装箱和拆箱的问题,一次两个装箱拆箱咱们彷佛能够忽略,可是大量的进行装箱和拆箱那就太损失性能啦.this
因为这样那样的问题,聪明的程序员就思考,怎么可以避免装箱拆箱问题,又能将代码变得简单可读的,就这样泛型就随之产生啦.来看看有了泛型以后上面的代码又会变成什么样呢?spa
/// <summary> /// 泛型方法 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="param"></param> public void PrintGenerics<T>(T param) { Console.WriteLine("this is a generics method print param: {0},this type is {1}", param,param.GetType()); } //使用 common.PrintGenerics<int>(1);
common.PrintGenerics(1);
这样就是一个泛型方法了.如今有几个疑问就是:
a: T是一个什么东西呢,之前都没有见过?
答: 从文档注释,对T的解释,T是一个类型参数,须要咱们传入具体的类型实参,T其实是一个占位符,在编译以后就变成了 `1这样一个占位符.
b: 在调用的时候为何能够省略<int>呢?
答: 编译器会根据传入的参数,来推断出具体的类型
c: 这种方式为何就比经过object来输出好呢?
答: 从上面的解释能够知道object是存在装箱和拆箱问题的,会损耗性能.而泛型就不存在装箱和拆箱的问题,由于从前面能够知道泛型是在编译的时候才知道类型,实际上编译器在咱们不知道的时候根据他的类型建立了相应数据类型的副本方法,好比:
common.PrintGenerics<int>(1); //建立的副本方法相似于 public void PrintInt(int i) { Console.WriteLine("this is a method print number: {0},this type is {1}", i, i.GetType()); }
这样就不存在值类型到引用类型的转换.
2: 泛型还有哪些应用呢?
泛型类,泛型接口,泛型方法,泛型返回,泛型约束
2.1: 泛型约束:
泛型约束是个什么东西呢?大概就是让参数知足它的条件(2333,解释不来 =_=||)
就好比:
common.PrintGenerics<Person>(new Person());
咱们此时的参数是一个person对象,那么咱们想输出person的名字,可是咱们发现这样是没有出现param.Name的.
这是为何呢?
由于此时咱们的参数没有添加约束,就至关因而一个object,那object里面有name属性吗?很显然是没有的.举个例子:就像咱们让一个"str"字符串输出它的name属性,是不现实的,由于没有.
这个时候咱们的约束就该上场啦
public void PrintGenericsPerson<T>(T p) where T: Person { Console.WriteLine("my name is :"+p.Name); }
泛型约束经过where来实现.
那么疑问又来了:
a: 约束后的效果是什么样呢?
答: 如今咱们就只能person类型以及它的子类型来做为参数啦.
b: 这样写和直接规定它的参数类型为person有什么区别吗?
答: 我的认为通常在肯定是person类型的时候,就不会在传入其子类型做为参数了,在作架构方面可能很是有用(我的理解不是很透彻)
c: 还有其余的约束吗?
答: class: 表示约束为引用类型(此时传一个数字就会出错). struct: 表示约束为值类型(DateTime为值类型). new(): 表示约束参数要有无参数的构造函数.等等
2.2: 泛型的静态成员变量
静态成员在相同的封闭类间共享.不一样的封闭类间不共享
开放类型:泛型类型没有指定具体的数据类型.
封闭类型:泛型类型指定了具体的数据类型.
2.3: 泛型方法的重载
a: 是在实例方法被调用的时候检查重载是否混淆,而不是在泛型类自己编译时检查
b: 当通常方法与泛型方法具备相同的签名时,会覆盖掉泛型方法,而使用通常的方法.