CS4L6——泛型约束
本章代码关键字
泛型约束
让泛型的类型有一定的限制,关键字:where
,泛型约束一共有6种,可以组合使用(部分约束不能组合使用)
值类型 —— where 泛型字母 : struct
引用类型 —— where 泛型字母 : class
存在无参公共构造函数 —— where 泛型字母 : new()
某个类本身或者派生类 —— where 泛型字母 : 类名
某个接口的派生类型 —— where 泛型字母 : 接口名
另一个泛型类型本身或者派生类型 —— where 泛型字母 : 另一个泛型字母
where 泛型字母 : (约束的类型)
各泛型约束讲解
值类型约束
where 泛型字母 : struct
限定泛型只能为值类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Test1 <T > where T : struct { public T value ; public void TestFun <K >(K v ) where K : struct { } } internal class Program { static void Main (string [] args ) { Test1<int > t = new Test1<int >(); t.TestFun(1.2f ); } }
引用类型约束
where 泛型字母 : class
限定泛型只能是引用类型的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Test2 <T > where T : class { public T value ; public void TestFun <K >(K v ) where K : class { } } internal class Program { static void Main (string [] args ) { Test2<Random> t2 = new Test2<Random>(); t2.value = new Random(); t2.TestFun(new object ()); } }
公共无参构造约束
where 泛型字母 : new()
使得泛型不能是没有 公共的无参构造函数 的非抽象类型(意味着抽象类是不能用的)
结构体一定有公共无参构造函数,因此值类型是可以用的
如果一个类,接口或者方法的泛型参数使用了公共无参构造约束,那么在内部,这个泛型参数就可以使用 new T()
来实例化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class Test3 <T > where T : new (){ public T value = new T(); public void TestFun <K >(K v ) where K : new () { } } abstract class Test { } class Test1 { } class Test2 { public Test2 (int a ) { } } internal class Program { static void Main (string [] args ) { Console.WriteLine("泛型约束" ); Test1<int > t = new Test1<int >(); t.TestFun(1.2f ); Test2<Random> t2 = new Test2<Random>(); t2.value = new Random(); t2.TestFun(new object ()); Test3<Test1> t3 = new Test3<Test1>(); Test3<int > t4 = new Test3<int >(); } }
类约束
where 泛型字母 : 类名
使得泛型只能是,某个类及其子类(该类的父类也不行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Test1 { }class Test4 <T > where T : Test1 { public T value ; public void TestFun <K >(K v ) where K : Test1 { } } class Test3 : Test1 { }internal class Program { static void Main (string [] args ) { Test4<Test1> t5 = new Test4<Test1>(); Test4<Test3> t6 = new Test4<Test3>(); t5.TestFun<Test4<Test1>>(t5); } }
接口约束
where 泛型字母 : 接口名
使得泛型只能是某个接口及其派生类型(类和接口)
(注意接口不可以实例化!!!)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 interface IFly { }class Test4 : IFly { }class Test5 <T > where T : IFly { public T value ; public void TestFun <K >(K v ) where K : IFly { } } internal class Program { static void Main (string [] args ) { Test5<IFly> t7 = new Test5<IFly>(); t7.value = new Test4(); Test5<Test4> t8 = new Test5<Test4>(); t8.value = new Test4(); } }
另一个泛型类型的泛型约束
where 泛型字母 : 另一个泛型字母
使得被约束的泛型只能是 约束泛型指定的类型本身及其派生类型
(用于有多个泛型字母的类型,将特定字母的泛型,限定为其他字母指定的类型或是派生类型)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 interface IFly { }class Test4 : IFly { }class Test6 <T , U > where T : U { public T value ; public void TestFun <K , V >(K v ) where K : V { } } internal class Program { static void Main (string [] args ) { Test6<Test4, IFly> t9 = new Test6<Test4, IFly>(); } }
约束的组合使用
可以将多个约束类型以逗号分割的形式来组合使用
注意,有些类型不能被组合使用,例如值类型约束和引用类型约束,公共无参构造约束(new()
)一定是写在最后一位!!!
1 class Test7 <T > where T : class , new () { }
多个泛型有约束
多个泛型有约束时,分别对他们使用 where
关键字,使用约束类型即可
用多个 where
连接即可,不需要逗号等多余的符号
建议继承和类的泛型约束分行写!以分清继承和泛型约束
1 2 3 4 class Test8 <T , K > : Test4 where T : class , new () where K : struct { }