泛型(Generic Paradigm)
C#2.0增加泛型类型,支持.Net Framwork2.0以上的框架。
工作原理:
在.net Framewrok 2.0 中,泛型在IL和CLR本身中具有本机支持。在编译泛型c#代码时,像其他任何类型一样,首先编译器会将其编译为IL,但是,IL只包含实际特定类型的参数或占位符,
并有专用的IL指令支持泛型操作。泛型代码的元数据中包含泛型信息。真正的泛型实例化工作是以“on-demand”的方式,发生在JIT编译时。当进行JIT编译时,JIT编译器用指定的类型实参来替换泛型IL代码元数据中的T,
进行泛型类型的实例化。这会像JIT编译器提供类型特定的IL元数据定义,就好像从未涉及到泛型一样。JIT编译器可以确保参数正确性,实施类型安全检查,甚至执行类型特定的IntelliSense。
当.net将泛型IL代码编译为本机代码时,所产生的本机代码取决于指定的类型。JIT编译器跟踪已经生成特定类型的IL代码,如果本机指定的是值类型,则JIT编译器将泛型类型参数替换为指定的值类型,
并且将其编译为本机代码。如果JIT编译器用已经编译为本机代码的值类型编译泛型IL代码,则只返回对IL代码的引用。因为JIT编译器在以后的所有场合中都将使用相同的值类型特定的IL代码,
所以不会存在代码膨胀问题。如果本机指定的是引用类型,则JIT编译器将泛型IL嗲没种的泛型参数替换为object,并将其编译为本机代码。在以后的任何针对引用类型而不是泛型类型参数的请求中,
JIT编译器只会重新使用实际代码,使用该代码,实例仍然按照它们离开托管堆的大小分配空间,并且不会存在强制类型转换。
泛型的主要思想是将算法与数据结构完全分离开,使得一次定义的算法能作用于多种数据结构,从而实现高度可重用的开发。
运用场景:泛型类、泛型接口、泛型方法、泛型委托。
我们在编程程序时,经常会遇到功能非常相似的模块,只是它们处理的数据类型不一样,这个时候,我们就可以考虑在这个模块内使用泛型了。并不需要单行返回值类型,因为你调用这个泛型类或者泛型方法的时候,就已经执行了返回值类型了,这时候这个返回值已经算是一个强类型参数了。
泛型约束有:①值类型约束 where T:struct ②引用类型约束 where T:class ③基类类型约束 where T: [Class_Name] ④接口类型约束 where T:[Interface_Name] ⑤构造函数约束 where T:new()
五种类型约束可以相互叠加共用。
.NET Framwork4.0之后出现的泛型的协变性(Out)和逆变性(in)。只能放在接口或者委托的泛型参数前面。协变性和逆变性都完全符合里氏替换原则。
协变性:Out关键字,泛型类型只能作用于返回值
逆变性:In关键字,泛型类型只能作用于参数。