[C#]泛型

泛型

  • 没有泛型时的问题
    • 用object实现的通用集合类型不安全,无法保证数据元素类型一致
    • 值类型会有额外的装箱拆箱开销
    • 类型特化的集合每有一个新类型就需要重新实现一遍
  • 泛型就是把类型作为参数,从而实现代码重用
  • C#的泛型在处理值类型的时候不会有装箱,节省性能和内存
  • 省去类型检查的性能开销
  • 相同泛型接口的不同构造被视为不同类型,一个类可以多次实现“同一个”泛型接口,虽然不建议,原因不知道没见过这种使用场景
  • 构造函数不要求类型参数
  • 可以用xxx = default提供任意类型的默认值
  • 仅类型参数个数不同的“相同”的类,应放到同一个C#文件中
  • 嵌套类型自动获得包容类型的类型参数,如果嵌套类型包含自己的类型参数T,会隐藏包容类型的类型参数T
  • 泛型约束可以约束基类,接口,类类型约束必须第一个出现,可以约束为Enum,Delegate和MulticastDelegate的子类
  • 可以约束为notnull,但不能与struct/class共同使用,因为后两个默认不可空
  • 约束为class时可以加个?表示约束为可空类型
  • struct不能在约束里写问号,但是可以在T后面写
  • new()构造函数约束,要求类型必须具有默认构造函数
  • 泛型类型参数和它们的约束不会被派生类继承,泛型类型参数不是成员
  • 派生类必须写自己的类型参数,加自己的约束,而且约束的严格性必须等同或更强于基类的约束,然后派生类的类型参数作为基类的类型实参
  • 重写虚泛型方法时约束隐式继承且不可以重新声明,额外的约束会破坏多态性,所以不允许新增约束,如果不会新增那自然默认可以继承约束就好了
  • 不能在约束之间指定OR关系

泛型方法

  • 在泛型类型和非泛型类型中都能声明泛型方法,泛型方法的类型实参可以自动推断,如果推断不准确,可以强转一下参数类型,或者指定类型实参
  • 允许使用和泛型类型的类型参数相同的方法指定约束

协变逆变

  • 协变逆变见另两篇
  • 协变转换的限制
    • 只有泛型接口和泛型委托可以协变,泛型类和结构永远不是协变的
    • 类型实参必须是引用类型,值类型不允许协变转换,因为值类型没有继承
  • 只有在从不写入时才能安全协变,只有在从不读取时才能安全逆变
  • C#是支持数组协变的,这是一个遗留的设计失误,要避免使用不安全的数组协变,将数组转换成只读接口IEnumerable<T>来使用协变性
  • IEnumerable<T>是只读的,它的迭代器的Current只有get
  • IList<T>Current是可写的

泛型实现方式

  • 值类型的类型参数,运行时会针对每个参数值类型创建一个具体化的版本,这样性能会比较好,同时代码避免了装箱
  • 引用类型就都是用object来实现,只留一个版本,减少代码量,避免代码膨胀
  • java加泛型的时候不想改jvm,所以不能为值类型支持泛型,值类型想塞进去只能装箱成引用类型,(我学java的时候也是因为这个特性直接java路转黑了太抽象了)而且jvm在执行的时候无法确定一个泛型类型实例的类型参数,导致反射受到了严重的限制。真有意思,java的假泛型被C#教材拿出来疯狂鞭尸
posted @   被窝儿  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示