目录
1.何为泛型
泛型(generic type)是指将数据类型的定义用参数表示,以达到在同一份代码上用于多种数据类型的操作,提高代码的复用。通过泛型可以定义类型安全的数据结构,而无须使用实际的数据类型,从而显著提高性能,并得到更高质量的代码。泛型类型不是类型,而是类型的模版。泛型编程是一种编程范式,它利用“参数化类型”将类型抽象化,从而实现更为灵活的复用。
比如,我们写一个交换函数,使用C语言编写的话,需要int型、float型等等的多个交换函数,但他们的内容却差不多,算法是一样的,这时候使用C编写效率很低。引入泛型后,可以完美地解决这个问题,通过传入参数即可。
static void Swap<T>(ref T a,ref T b)
{
T temp;
temp = a;
a = b;
b = temp;
}
2.泛型类
2.1定义
访问修饰符 class 泛型类名<类型参数列表>
{
类的成员;
}
2.2实例
定义泛型类
public class Point<T1,T2>
{
public T1 x;
public T2 y;
public override string ToString()
{
return string.Format("{0},{1}", x, y);
}
}
调用泛型类
static void Main(string[] args)
{
Point<float,int> point1 = new Point<float,int>();
Point<int, float> point2 = new Point<int, float>();
point1.x = 2.3f; point1.y = 1;
point2.x = 3; point2.y = 3.5f;
Console.WriteLine(point1.ToString());
Console.WriteLine(point2.ToString());
}
3. 泛型类的约束
3.1 基类约束
限制了类型参数列表只能是继承至基类名的子类。
访问修饰符 class 泛型类名<类型参数列表> where 类型参数 : 基类名
{
类的成员;
}
3.2 接口约束
限制了泛型类型只能是实现了某接口的类。
访问修饰符 class 泛型类名<类型参数列表> where 类型参数 : 接口名
{
类的成员;
}
3.3 默认构造函数约束
限制了泛型类型只能含有无参数的构造函数
访问修饰符 class 泛型类名<类型参数列表> where 类型参数 : new()
{
类的成员;
public 泛型类名() /*无参构造函数*/
{
构造函数体;
}
}
4. 泛型类中的静态成员
两个不同数据类型的泛型,那么其中的静态成员是不一样的。也就是说,其实两个类并不是同一个类。
5. 泛型类的继承
5.1非泛型类继承泛型类
非泛型类继承泛型类,那么泛型类的类型必须实例化。
class A<T>
{
}
class B : A<int> //泛型的类型已经实例化为A<int>
{
}
5.2 泛型类继承非泛型类
泛型类可以继承非泛型类
class A
{
}
class B<T> : A
{
}
5.3泛型类继承泛型类
class C<U, V>
class D:C<string, int>
// E类型为C类型提供了U、V,也就是说来源于子类
class E<U, V> : C<U, V>
//F类型继承于C<string, int>,可以看成F继承一个非泛型的类
class F<U, V> : C<string, int>
6. 泛型方法
访问修饰符 返回值类型 方法名<类型参数列表>(形参列表) where 类型参数 : 约束条件
{
方法体;
}
如交换函数:
static void Swap<T>(ref T a,ref T b)
{
T temp;
temp = a;
a = b;
b = temp;
}
int a = 1, b = 2;
Swap<int>(a, b);
如类中的泛型函数:
在调用泛型方法时,C#编译器基于传入的参数类型来推断出正确的类型,并且它允许完全省略类型规范,称为泛型推理。
public class MyClass
{
public T SomeMethod<T>(T t)
{
return t;
}
}
MyClass myClass1 = new MyClass();
myClass1.SomeMethod(3);//泛型推理机制调用泛型方法,按int调用泛型方法