泛型约束一共有六种:
约束的是字母T,程序中调用的T是什么类型,就要用什么样的类型
1.值类型,where 泛型字母:struct;
Class Test1<T> where T:struct
{
public T value;
public void TestFun<K>(K v) where K:struct
{
}
}
以上是定义了值类型为struct的类,里面有变量和方法
如果在主函数中声明为
Test1<Object> t=new Test1<Object>();
Vs会报错
为何会报错?转到定义可知
Objcet是引用类型
换成Test1<int> t=new Test1<int>();
//无报错
//再举例Test1中的函数
t.TestFun<Random>(new Random());
//会报错
因为Random也是引用类型
改为t.TestFun<float>(1.4f);
转到速览定义float可知,float是结构体
2.引用类型,where 泛型字母 class
值类型声明的Object和Random在引用类型不会报错,因为约束的字母T就是要用引用类型填入
3.存在无参公共构造函数,where 泛型字母:new()
举例来说 还是定义一个Test类 类中也有变量和函数 此外 再声明两个类 一个有默认构造函数 一个自定义了一个构造函数
Class Test<T> where T:new ()
{
public T value;
public void TestFun<K>(K k) where K:new ()
{
}
}
Class Test1
{
}
Class Test2
{
public Test2(int a){}
}
回到主函数
Test<Test1> t=new Test<Test1>();//不会报错 test1默认有无参构造函数
但是 要是将test1换为test2 则会报错 因为test2中的无参构造函数被顶掉了
当然 要是test1将自己的无参构造函数设置为private 注意这种类型约束说的是无参公共构造函数 将test1中的无参构造函数的访问级别设置为private 则程序会报错
题外话:结构体中即使写了有参构造 无参构造并不会被顶掉 所以将test1换成struct类型的结构体 不会报错
那么,抽象类呢?要清楚 抽象类是不能new的 既然不能new 那么Test<Test1> t=new Test<Test1>();会报错
4某个类本身或者其派生类,where 泛型字母:类名
class Test<T> where T:Test1
{
public T value;
public void TestFun<K>(K v) where T:Test1{};
}
class test1{}
class test2:test1{}
回到主函数声明一个类
Test<test1>() t=new Test<test1>();//无报错
Test<test2>() t=new Test<test2>();无报错 test2是test1的派生类
问号:如果是Object类呢?不可以 Object是所有类的父类 也就是说Object是test1的父类 test1的子类和它本身可以填入 但是语法未规定test1的父类也可以填入
5.某个接口的派生类型,where 泛型字母:接口名
接口和4一样
class test1:Ifly{}
c;ass test<T> where T :Ifly
{
public T value;
public void TestFun<K>(K k) where T:Ifly{}
}
//Main函数
test<test1>() t=new test<test1>();
test1继承Ifly接口 所以未报错
6.另一个泛型类型本身或派生类型.where 泛型字母:另一个泛型字母
class test<T,U> where T:U
{
public T value;
public void TestFun<K,V>(K k) where T:V{};
}
解析:要不U是T本身 要不T是U的派生类
7.问题:以上泛型约束是否可以组合使用
回答是肯定的.
class test<T> where T:class,new(){}//这个组合可以
class test<T> where T:struct,new(){}//报错
struct有公共的无参默认构造函数 再写new()就画蛇添足了
简而言之 泛型约束之间进行组合使用 无明确规则 语法和实际使用时不冲突就行
8.如果有多个需要约束的泛型呢?
举个例子就清楚了
class test<T,K> where T:class,new()
where K:class,new()
{}
写完第一个约束 接着写第二个泛型约束就行
趁热打铁:在泛型六种约束的基础上 写一个单例模式基类