C# 泛型约束(where)的使用小结
一、泛型约束 核心概念
1. 为什么需要泛型约束
普通泛型<T>:T 可以是任意类型,范围太大,无法使用指定类型的专属方法、属性。
泛型约束:通过 where T : 约束条件,缩小泛型类型范围,限制 T 只能是指定类型。
2. 约束语法
static void 方法名<T>(T 参数) where T : 约束条件
{
}
二、六大泛型约束
1. 无约束(任意类型)
语法:无 where 条件
规则:T 可以是值类型、引用类型、自定义类、接口、数组任意类型
// 无任何限制的泛型方法
static void Test1<T>(T a)
{
Console.WriteLine("Test1");
}
2. 值类型约束struct
语法:where T : struct
规则:T 只能是值类型(int、double、bool、结构体)
禁止:所有引用类型(string、数组、自定义类)
static void Test2<T>(T a) where T : struct
{
Console.WriteLine("Test1");
}
// 正确:int是值类型
Test2(10);
// 报错:数组是引用类型,违反struct约束
// Test2(new int[] {1});
3. 引用类型约束class
语法:where T : class
规则:T 只能是引用类型(类、接口、数组、string)
禁止:所有值类型(int、double、bool)
static void Test3<T>(T a) where T : class
{
Console.WriteLine("Test1");
}
// 报错:int是值类型
// Test3(10);
// 正确:string是引用类型
Test3("ss");
4. 无参构造函数约束new()
语法:where T : new()
规则:T 类型 必须拥有无参构造函数
适用场景:泛型方法内部需要 new T() 实例化对象
static void Test4<T>(T a) where T : new()
{
Console.WriteLine("Test1");
}
// People类有无参构造函数,合法
Test4(new People());
注意:如果类只写了有参构造、没有无参构造,会直接报错。
5. 基类约束(父类约束)
语法:where T : 父类名
规则:T 只能是指定父类 或 父类的派生类
static void Test5<T>(T a) where T : People
{
Console.WriteLine("Test1");
}
Test5(new People()); // 父类本身
Test5(new Stu()); // 子类派生类,合法
6. 接口约束
语法:where T : 接口名
规则:T 必须是 实现了该接口的类 / 派生类
static void Test6<T>(T a) where T : IPeople
{
Console.WriteLine("Test1");
}
// SS类实现了IPeople接口,合法
Test6(new SS());
三、约束优先级与组合规则
struct和class不能同时使用(互斥)new()必须放在所有约束的最后面- 可以多约束叠加:例如
where T : class, IPeople, new()
四、所有报错原因汇总
Test2(new int[]{1})报错:数组是引用类型,Test2 约束必须是值类型 structTest3(10)报错:int 是值类型,Test3 约束必须是引用类型 class
五、六大约束 终极对照表(背诵神器)
约束写法 | 允许类型 | 禁止类型 |
|---|---|---|
无约束 | 全部类型 | 无 |
struct | 所有值类型 | 引用类型(类、数组、string) |
class | 所有引用类型 | 值类型(int、bool、double) |
new() | 有无参构造的类 | 无无参构造的类 |
父类名 | 父类、子类 | 无关类、接口 |
接口名 | 实现该接口的类 | 未实现接口的类 |
六、满分背诵口诀
- 无约束通吃所有,范围最大最自由
- struct只吃值类型,数组类全报错
- class只吃引用类,数值类型进不来
- new()要求无参构,实例化不报错
- 父类约束认子孙,接口约束认实现
到此这篇关于C# 泛型约束(where)的使用小结的文章就介绍到这了,更多相关C# 泛型约束内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!


最新评论