当前位置: 首页 > news >正文

C# 中常见的 五大泛型约束

在 C# 中,泛型(Generics)允许你定义类型安全且可重用的代码,而不必指定具体的类型。为了更精确地控制泛型类型的行为,可以使用泛型约束(Generic Constraints)来限制泛型类型参数的类型。泛型约束通过 where 关键字来实现。

以下是 C# 中常见的 五大泛型约束,它们有助于限定泛型参数的类型特性:

1. where T : struct

值类型约束
这个约束指定 T 必须是值类型。值类型包括结构体(struct)、枚举(enum)以及基本数据类型(如 int, float, bool 等)。

应用场景

  • 当你只需要值类型时,使用此约束可以确保类型安全。
  • 不能将引用类型(如类或接口)传递给此约束。

示例

public void PrintValueType<T>(T value) where T : struct
{Console.WriteLine(value);
}

限制

  • 不允许使用 null 值,因为 null 是引用类型的标志。所有的值类型默认是不可空的(除非使用 Nullable<T>)。

2. where T : class

引用类型约束
这个约束指定 T 必须是引用类型。引用类型包括所有类、接口、委托等。

应用场景

  • 当你需要保证传递的类型是引用类型时使用该约束。
  • class 限制也排除了值类型和指针类型。

示例

public void PrintReferenceType<T>(T value) where T : class
{Console.WriteLine(value.ToString());
}

限制

  • 可以传递 null 值,因为引用类型默认可以为 null

3. where T : new()

无参数构造函数约束
这个约束要求 T 必须有一个无参构造函数。通过这个约束,确保你能够在泛型方法或类中使用 new 运算符来创建 T 类型的实例。

应用场景

  • 当你希望在泛型类型中实例化对象时,这个约束非常有用。
  • 常常和其他约束一起使用,确保泛型类型能够被实例化。

示例

public T CreateInstance<T>() where T : new()
{return new T();
}

限制

  • 类型 T 必须有一个无参数的构造函数。如果 T 没有无参构造函数,编译时会报错。

4. where T : BaseClass

基类约束
这个约束指定 T 必须是 BaseClass 类型或其派生类型。也就是说,T 必须继承自某个指定的类。

应用场景

  • 当你只想使用某个基类及其子类时,使用这个约束。
  • 这允许你访问基类和派生类的成员,而不需要在泛型类型中使用具体的类型。

示例

public void PrintBaseClass<T>(T obj) where T : BaseClass
{obj.PrintInfo();
}

限制

  • T 必须是 BaseClass 或其子类,不能是其他类。

5. where T : IInterface

接口约束
这个约束指定 T 必须实现某个接口。通过这种方式,可以确保泛型类型实现了接口中的方法和属性。

应用场景

  • 当你想保证泛型类型实现了特定接口时使用此约束。
  • 可以用于保证类型具备接口定义的行为,比如 IComparableIDisposable 等常用接口。

示例

public void PrintComparable<T>(T obj) where T : IComparable
{int result = obj.CompareTo(default(T));Console.WriteLine($"Comparison result: {result}");
}

限制

  • 类型 T 必须实现 IInterface 接口。如果类型没有实现接口,会导致编译错误。

组合多个约束

你还可以将多个约束组合起来使用。例如,你可以要求 T 同时满足多个条件:

public void ProcessData<T>(T obj) where T : class, IComparable, new()
{// 类型 T 必须是引用类型、实现了 IComparable 接口,并且有一个无参构造函数
}
http://www.dtcms.com/a/350856.html

相关文章:

  • [系统架构设计师]应用数学(二十一)
  • 云计算学习笔记——Linux用户和组的归属权限管理、附加权限、ACL策略管理篇
  • 联邦雪框架FedML自学---第四篇---案例一
  • 浅谈:运用幂的性质
  • 程序的“烽火台”:信号的产生与传递
  • 【基础-单选】使用http发起网络请求,需要以下哪种权限?
  • C6.2:小信号、交流电流增益分析
  • 立轴式小型混凝土搅拌机的设计含14张CAD
  • 客户生命周期价值帮助HelloFresh优化其营销支出
  • 快速了解工业相机中的连续采集、软触发、硬触发和同步触发以及PTP同步触发
  • Spring介绍
  • Linux iptables 防火墙
  • Linux网络编程基础API
  • [灵动微电子六步换向(方波控制)方案MM32BIN560C] 六步换向实现和规律
  • PostgreSQL诊断系列(2/6):锁问题排查全攻略——揪出“阻塞元凶”
  • RK3568 Linux驱动学习——pinctrl和gpio子系统
  • onnx入门教程(四)——ONNX 模型的修改与调试
  • Day24: NumPy 奥德赛:用科学计算的魔法征服数据宇宙!
  • 32.Ansible平台搭建
  • 2024年09月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • NFC线圈设计计算
  • 力扣热题——前K个高频元素
  • 记一次Arrays.asList集合删除的错误
  • Java vs Kotlin 在实际开发中的主要区别与面试题总结
  • 太阳光模拟器在国防军工中的应用
  • k8s-容器化部署论坛和商城服务(小白的“升级打怪”成长之路)
  • K8s Pod驱逐机制详解与实战
  • SpringBoot防重放攻击的5种实现方案
  • 什么是数据库?现代数据库类型、示例与应用(2025)
  • 深入理解 iptables:Linux 防火墙从入门到精通