- 概述
泛型其实我们在日常开发中都有用过,T List集合等,目的是为了不同类型创建相同的方法或类,也包含接口,委托的泛型,比如ORM的映射,一个方法通过传入不同的类,返回不同的实例,在调用是才确定参数类型。
我们所知的值类型分配在线程栈上,引用类型分配在堆上,只把指针存放在栈中。例如:
int i = 1;object x = i;i = (int)x;
这就是一个装箱和拆箱的过程。但是这样的拆箱和装箱过程意味着内存的消耗,特别是ArrayList是类型不安全的,操作时需要大量的进行装箱和拆箱的过程,性能消耗会特别大。
但是如果我们在定义List时指定了类型,那么就不会出现装箱和拆箱的操作。如:List,再进行操作时就不会进行拆箱和装箱了,而这个就是类型安全 - 泛型的使用
2. 1.泛型方法
常见的泛型方法就是在方法后面带上(T param),T可以随便定义,只要不是关键保留字就行 ,默认约定俗称都用T,这里就代表你定义了一个T类,然后后面参数就可以用这个T类,这样就可以用一个方法,满足不同的参数类型,去做相同的事情,例如ORM的Insert(T param);
把参数的类型申明推迟到调用时,延迟声明。这是一种延迟思想,延迟以达到更好的扩张。
public static void Show<T>(T value){ Console.WriteLine(value);} Show<int>(123);
2. 2.泛型类,泛型接口
创建泛型类或接口与创建方法类型,语法一样,例如List ,用来满足不同的具体类型,完成相同的事情
public class Test<T>{public T _t;} public interface ITest<T>{T GetT();}
3.泛型的功能
3.1.泛型的默认值
我们一般用default关键字来为泛型类型初始化。
3.2.泛型的约束
泛型导致任何类型都可以进来,那么如何去使用这个类型T,编写的时候我们不知道T是什么,也不知道他能做什么。一个方法可以用反射,任何一个类型通过反射都能获取内部的结构属性方法调用。泛型约束提供更简单的方法。在声明泛型时在参数后面追加where关键字。约束可以指定多个,像 where T: People,Iwork,new().约束传进来的类People或其子类,并继承Iwork接口,有无参数构造函数。
public static void Show<T>(T value) where T :People{Console.WriteLine(value.Name);}
3.3.协变逆变
协变逆变就是对参数和返回值的类型进行转换。协变用一个派生类更大的类去替代某个类型(小代替大),其实就是设计原则的里氏替换原则,比如狗集成了动物,那么任何动物作为参数类型的地方,调用时都可以用狗替换。逆变则时反过来
public void Show(Animal animal){} Show(dog);
泛型接口的协变逆变。如果泛型类型用了out关键字标注,泛型接口就是协变的。那么意味着返回的类型只能是T。如果用了in关键字标注,那么就是逆变,只能把泛型类型T作为方法的输入。
4.泛型的委托
以Action为例,Action是.NET Framework内置的泛型委托,可以使用Action委托以参数形式传递方法,而不用显示声明自定义的委托。内置的Action和Func可以便于我们统一。Action无返回值委托,可以传入不同的类型
5.总结
通过泛型类可以创建独立于类型的类,泛型方法创建出独立于类型的方法。接口,结构,委托也可以用泛型的方式创建。当我们设计与类型无关的对象时,可以使用泛型,由调用方去决定类型。
这世间万物都遵循着一个规则,任何事物都需要由简入繁,再由繁入简。最终达到道归一的境界。
浙公网安备 33010602011771号