<p>where 关键字在 C# 中强制声明泛型参数的约束条件,如 class、struct、new()、接口或基类继承等,多个约束用逗号分隔,不可混用互斥约束(如 class 与 struct),且约束位置紧随泛型参数列表之后。</p>

where 用于指定泛型类型必须满足的条件
在 C# 中,where 关键字不是可选修饰,而是编译器强制要求你明确声明泛型参数的能力边界。不加约束时,T 只能调用 object 的成员(如 ToString()、Equals()),一旦想调用 T.Method() 或 new T(),就必须用 where 告诉编译器“这个 T 至少得是某种类型”。
常见 where 约束写法与对应能力
每种约束解锁一组操作权限,混用时顺序无关,但需注意逻辑兼容性:
-
where T : class—— 允许为null,禁止值类型;不能和struct同时出现 -
where T : struct—— 要求是值类型(含int、DateTime、自定义struct),自动排除null -
where T : new()—— 要求有无参 public 构造函数;单独用时不限制引用/值类型,但和class搭配更常见 -
where T : IComparable—— 要求实现指定接口,可调用IComparable.CompareTo() -
where T : BaseClass—— 要求继承自某个类(只能一个),且该类不能是sealed -
where T : U—— 要求T是另一个泛型参数U的子类型(常用于方法嵌套泛型)
多个约束怎么写?注意逗号分隔,不能用 and/or
多个约束之间用英文逗号分隔,没有逻辑运算符。例如:
public static T CreateInstance<T>() where T : class, new(), ICloneable
{
return new T(); // ✅ 允许 new,因为有 new();✅ 可调 Clone(),因为实现了 ICloneable
}错误写法:where T : class && new() 或 where T : class and new() —— 编译直接报错 CS0412 或 CS0701。
特别注意:class 和 struct 互斥;new() 与 struct 可共存(因所有 struct 隐式含无参构造),但与 class 共存时,实际要求该 class 必须显式声明 public 无参构造。
where 在泛型方法和泛型类型中的位置差异
约束始终紧跟在泛型参数列表之后、方法签名或类型体之前:
// 泛型方法:约束在方法名后、参数列表前
public static void Swap<T>(ref T a, ref T b) where T : IComparable { ... }
<p>// 泛型类:约束在类名后、基类/接口继承列表前
public class Repository<T> : IRepository<T> where T : class, new() { ... }</p><p>// 多泛型参数:每个参数可独立约束
public static TOutput Convert<TInput, TOutput>(TInput input)
where TInput : IConvertible
where TOutput : struct => ...容易忽略的一点:如果泛型类本身有约束,其内部泛型方法可以复用或收紧这些约束,但不能放宽——例如类已限定 where T : class,方法里再写 where T : struct 会编译失败。


















