where 约束
约束类型参数。
where 约束 是 CoddyKit 上的免费 C# Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 4 节课。
约束存在的原因
默认情况下,类型参数 T 几乎会被当作 object 处理,因此编译器只允许对它执行很少的操作。使用 where 编写的约束会向编译器提供更多关于 T 的信息。
有了这些信息,您就可以安全地调用方法、创建实例或比较值。
void Show<T>(T value) where T : IFormattable
{
// now ToString(format, provider) is available
}接口约束
接口约束要求 T 实现指定的接口。这样,方法体就可以调用该接口的成员。
下面的 where T : IComparable<T> 保证存在 CompareTo 方法。
T Max<T>(T a, T b) where T : IComparable<T>
=> a.CompareTo(b) >= 0 ? a : b;基类约束
您可以要求 T 派生自指定的基类。这样,泛型代码内部就可以使用该基类的成员。
在所有实体共享同一个基类型的框架中,这种做法很常见。
class Animal { public string Name = ""; }
string NameOf<T>(T a) where T : Animal => a.Name;class 约束
where T : class 要求 T 为引用类型。这样就可以为其赋值 null,并检查引用相等性。
仓储、缓存以及任何存储可为空引用的组件通常都会使用它。
T? FindOrNull<T>(bool found, T value) where T : class
=> found ? value : null;struct 约束
where T : struct 要求 T 为不可为空的值类型。这样,您可以将 T 作为值类型处理,并使用 T? 表示可为空的值类型。
只处理数字、枚举或小型结构的辅助工具会使用这种约束。
T? AsNullable<T>(T value) where T : struct
=> value;new() 约束
new() 约束要求 T 具有公共无参数构造函数。这样,方法体就可以编写 new T()。
工厂和对象池依靠此约束以泛型方式创建实例。
using System;
class Program
{
static T Make<T>() where T : new() => new T();
static void Main()
{
var list = Make<System.Collections.Generic.List<int>>();
Console.WriteLine(list.Count);
}
}组合约束
您可以为一个参数应用多个约束。排序规则要求先写 class 或 struct,然后是基类,接着是接口,最后写 new()。
这些约束写在单个 where 后面,并用逗号分隔。
T Build<T>() where T : class, IComparable<T>, new()
=> new T();多个 where 子句
当方法或类包含多个类型参数时,每个参数都有自己的 where 子句。它们会依次书写。
这样可以清楚地区分每个参数对应的约束。
TResult Convert<TInput, TResult>(TInput x)
where TInput : class
where TResult : new()
=> new TResult();可运行的约束示例
这个完整程序使用 IComparable<T> 约束查找两个值中较大的一个,同时适用于整数和字符串。
正是该约束使方法内部调用 CompareTo 成为合法操作。
using System;
class Program
{
static T Max<T>(T a, T b) where T : IComparable<T>
=> a.CompareTo(b) >= 0 ? a : b;
static void Main()
{
Console.WriteLine(Max(3, 9));
Console.WriteLine(Max("apple", "pear"));
}
}notnull 和 unmanaged 约束
较新版本的 C# 增加了更多约束。where T : notnull 禁止可为空的类型,适合用作字典键。where T : unmanaged 将 T 限制为可直接映射的值类型,适用于底层代码。
这些约束可以在专门的场景中进一步提高安全性。
void Use<T>(T key) where T : notnull { }
unsafe void Raw<T>(T v) where T : unmanaged { }约束带来能力,而非限制
约束看起来像是在限制类型,但实际上会解锁更多能力。没有约束时,您几乎无法操作 T;有了约束后,就可以使用它的成员。
请选择能让算法正常工作的最小约束,从而尽可能保持类型参数的灵活性。
// No constraint: only object members available
string Name<T>(T x) => x.ToString();快速检查
测试您对 where 约束的理解。
总结
where 子句用于约束类型参数,包括接口、基类、class、struct、new()、notnull 和 unmanaged。每种约束都会为 T 解锁特定操作。
请按照正确顺序排列约束,为每个参数使用一个子句,并选择算法所需的最小约束。
常见问题解答
「where 约束」课时是免费的吗?
是的 — 「where 约束」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 4 节课。
「where 约束」这节课中我会学到什么?
约束类型参数。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C# Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「where 约束」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C# Academy 课中编写并运行代码吗?
能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。