1.泛型:通过 "参数化类型" 来达到类型的抽象化,从而得到更好的面向对象体验 泛型其实也就是类的一个参数,但是参数必须是一个类不能是一个对象
2.C#泛型由CLR运行时支持,(CLR是公共语言运行库,/公共语言运行时)
泛型的特点:采用”基类,接口,构造器,值类型/引用类型”四种约束来对类型参数的”显示约束”
泛型语法:单独声明
4.泛型编译中如GenericStack<T>生成泛型的代码和元数据,它不会进行实例化,因为T它只是一个占位符,可以用一个类型来替换T这就是所谓的泛型实例化
5.泛型接口的类型参数要么已实例化,要么来源于实现类声明的类型参数
class C<U,V>{} //合法 class D: C<string,int>{} //合法 class E<U,V>:C<U,V>{}//合法 class F<U,V>:C<string,int>{}//合法 class G:C<U,V>{} //非法 //泛型类型的成员 class C<V>{ public V f1; //声明字段 public D<V> f2; //作为其他泛型类型的参数 public C(V x) { this.f1 = x; } }
6.泛型类型的成员可以使用泛型类型声明中的类型参数。但类型参数如果没有任何约束,就只能在该类型上使用从Object继承的公有成员。
7.泛型委托:泛型委托支持在委托返回值和参数上应用参数类型,这些参数类型同样可以附带合法的约束
8.泛型类中的方法重载:
class MyClass { void F1<T>(T[] a, int i); // 不可以构成重载方法 void F1<U>(U[] a, int i); void F2<T>(int x);// 可以构成重载方法 void F2(int x); //两句申明一样,where字句,T继承A,泛型参数必需要继承A void F3<T>(T t) where T : A; //不可以构成重载方法 void F3<T>(T t) where T : B; }
9.泛型约束:
对“所有泛型类型或泛型方法的类型参数”都要基于"显示的约束"维护
C#所要求的类型安全。
显示约束是由where子句表达可以指定“基类约束”,“接口约束”,“构造器约束”“值类型/引用类型约束”四种约束.
如果没有指定显示"类型约束"时,泛型类型参数将只能访问Object类型中的共有方法。
class A { public void F1() {…} } class B { public void F2() {…} } class C<S,T> where S: A // S继承自A where T: B // T继承自B { // 可以在类型为S的变量上调用F1, // 可以在类型为T的变量上调用F2 …. }
10.泛型的优点:
•代码重用
泛型提供的代码的重用,确切的说应该是 "逻辑和算法的重用"
从前面的泛型方法例子可以看到,通过泛型可以避免为每种特定的类型实现一个比较方法。
•类型安全
泛型类型保证了类型安全,可以在编译期就发现类型不匹配的问题,而不是等到运行时
•效率
避免值类型的装箱和拆箱引起的效率问题(后面会简单介绍为什么泛型可以避免装箱和拆箱)