泛型实现了一种将类型抽象化的通用处理方式。泛型本质上就是一种代码重用。泛型类与非泛型类的主要区别是类型参数化。
约束是指在定义泛型类时,对于能够用于实例化类型参数的类型所做的限制;约束是通过where子句来实现的,多个约束之间以逗号隔开。
如果实现一个object类不支持的任何方法,则需要对类型参数实现约束。具体为:
class MyArray<T> where T:dd,new()
{
}
该方法主要为MyArray添加了约束dd和new(),意指MyArray只能管理dd类型及其派生类型对象,同时必须实现一个公共的无参的构造函数。
约束的主要包括:构造器约束、值类型约束、引用类型约束、基类约束、接口约束、和裸类型约束,具体为:
1.T:new(),表示类型参数必须具有公共无参数构造函数,有多个约束存在时,必须将new()约束置于最后;
2.T:struct,表示类型参数必须是值类型。
3.T:class,表示类型参数必须是引用类型。class和struct不能同时指定。
4.T:基类名,表示类型参数必须是基类及其派生类型,例如:T:dd。不能既指定约束基类,又指定calss.
5.T:接口名,表示类型参数必须是指定的接口或是实现了该接口的接口,可以同时定义多个约束;例如:
public class List<T>:IList<T>,ICollection<T>
泛型方法的重载:
public class Test<T, V>
{
public T add(T a, V b) //第一个方法
{
return a;
}
public T add(V a, T b) //第二个方法
{
return b;
}
public int add(int a, int b) //第三个方法
{
return a + b;
}
}
很明显,上面Test类中的第三个具有相同的方法名,如果同时传入 Test<int, int>,三个方法都会匹配,但是泛型会优先匹配非泛型方法,所以他会自动匹配到第三个方法;如果将第三个方法进行屏蔽,则会报错,提示方法和属性之间调用不明确。
Test<int, int> node = new Test<int, int>();
object x = node.add(2,11);
如果传入的参数如下所示,它会编译通过,因为传入的参数类型不一致,它可以找到唯一匹配的方法;
Test<int, string> node1 = new Test<int, string>();
object x1 = node1.add(2, "11");
综上所述:可以看出,当非泛型方法和泛型方法重载时,它会优先匹配非泛型方法。