0

0

C# 泛型(Generics)的约束有哪些 - where关键字的高级用法

星降

星降

发布时间:2025-12-30 09:50:03

|

157人浏览过

|

来源于php中文网

原创

泛型约束(where子句)是编译期类型安全的关键机制,用于限定泛型参数可接受的类型,支持成员访问、实例化及协变/逆变等操作,共六类:class/struct、基类/接口、new()、in/out、组合约束及泛型参数约束。

c# 泛型(generics)的约束有哪些 - where关键字的高级用法

泛型约束的核心作用

泛型约束(where子句)不是可选项,而是让编译器在编译期就验证类型安全的关键机制。它限制了泛型参数能接受哪些具体类型,从而允许你在泛型代码中调用这些类型支持的操作——比如调用方法、访问属性、使用 new() 创建实例,或者进行特定的类型转换。

六类常见 where 约束及其典型用途

class / struct:限定引用类型或值类型

  • where T : class —— 确保 T 是类、接口、委托或数组(即非值类型),可用于判空或作为引用传递
  • where T : struct —— 确保 T 是不可为 null 的值类型(不含 Nullable),常用于高性能数值计算场景

基类或接口约束:启用成员访问

  • where T : IComparable —— 可直接调用 CompareTo()
  • where T : Animal, ICloneable —— 支持多约束,T 必须继承 Animal 并实现 ICloneable
  • 注意:基类必须写在接口前面,且只能有一个基类

构造函数约束new()

  • where T : new() —— 要求 T 具有无参公共构造函数
  • 常与其它约束组合使用,例如 where T : class, new(),适用于工厂模式或 ORM 实体创建
  • 不支持带参构造函数;若需更灵活初始化,应改用工厂委托或抽象工厂

协变与逆变约束(仅适用于泛型接口/委托)

Winston AI
Winston AI

强大的AI内容检测解决方案

下载
  • in T(逆变):T 仅作输入参数,如 IComparer,允许 IComparer 赋值给 IComparer
  • out T(协变):T 仅作返回值,如 IEnumerable,允许 IEnumerable 赋值给 IEnumerable
  • 协变/逆变需显式标注,且受类型安全性严格限制(不能同时 in 和 out 同一类型)

组合约束与实用技巧

多个约束可用逗号分隔,顺序有要求:基类 → 接口 → new()

  • 正确:where T : Product, IValidatable, new()
  • 错误:where T : new(), IValidatable, Product(编译失败)

泛型类型参数还可约束为另一个泛型参数:

  • class Container where T : class where U : T —— 表示 U 必须是 T 或其派生类
  • 这在构建类型安全的容器、策略链或泛型树结构时很实用

约束不是万能的 —— 注意边界情况

约束只影响编译期检查,运行时仍可能遇到装箱/拆箱、null 引用或隐式转换问题

  • where T : class 不排除 nullable 引用类型(C# 8+ 默认开启 nullable reference types 后才可区分)
  • where T : struct 排除了 Nullable(即 int?),因为它本质是泛型结构体,但编译器特殊处理,不能直接用在 struct 约束中
  • 接口约束无法保证具体实现行为(比如 IComparable.CompareTo 是否真正按预期比较),仍需运行时逻辑校验

基本上就这些。合理使用 where 约束,能让泛型既保持通用性,又获得接近非泛型代码的类型提示和安全保证。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

311

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

228

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

433

2024.03.01

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

193

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

185

2025.07.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

311

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

518

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

48

2025.08.29

俄罗斯搜索引擎Yandex最新官方入口网址
俄罗斯搜索引擎Yandex最新官方入口网址

Yandex官方入口网址是https://yandex.com;用户可通过网页端直连或移动端浏览器直接访问,无需登录即可使用搜索、图片、新闻、地图等全部基础功能,并支持多语种检索与静态资源精准筛选。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1

2025.12.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go语言教程-全程干货无废话
Go语言教程-全程干货无废话

共100课时 | 9.4万人学习

Redis+MySQL数据库面试教程
Redis+MySQL数据库面试教程

共72课时 | 6.2万人学习

如何进行WebSocket调试
如何进行WebSocket调试

共1课时 | 0.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号