C#泛型与约束

前言

最近在看一些项目和框架,用了好多泛型,虽然C++模板比较熟,但是泛型却接触的比较少,所以看了CLR的泛型后打算写个文章记录下方便以后自己看。(其实和模板差不多!)

泛型

介绍

泛型是CLR和编程语言提供的一种特殊机制,它支持另一种形式的代码重用,也就是算法重用,比如泛型List类的List< T >表名它操作的是一个未指定的数据类型,到时候使用泛型类型或者方法时指定的具体数据类型称为类型实参,也就是用具体的类型实参来代替T

优点

  1. 源代码保护,开发人员不需要访问算法的源代码,而模板编程需要访问源代码(为什么?)
  2. 代码可重用性
  3. 类型安全,将具体的类型用于泛型算法的时候,必须与指定数据类型兼容才能用于算法,否则会有异常。
  4. 更佳的性能,没有泛型的时候就要用Object来模拟泛型。如果操控值类型就要进行拆装箱,会造成性能损耗和频繁的垃圾回收,也就是ArrayList和List的差别。

到底有多大的性能差别?
看书上写的是操作Int32也就是值类型的时候,泛型比object快7倍。如果都操作string引用类型的话,就差不多,因为都不用拆装箱。

开放类型和封闭类型

具有泛型类型参数的类型称为开放类型,CLR禁止构造开放类型的任何实例
比如T t = typeof(T)
为所有类型参数传递了实际的数据类型,类型就称为封闭类型

泛型类型同一性

因为泛型类型写起来比较复杂,比如

List<DataTime> dt1 = new List<DateTime>();

有些人就想偷懒,用一个非泛型类型从泛型类型派生,并制定了类型实参。

internal sealed class DateTimeList : List<DateTime>{}
//然后
DateTimeList dt1 = new DateTimeList();

虽然很方便,但是这是是错的!!这样会影响类型相等性
真正简化的语法!

相当于一个别名啦~

using DateTimeList = System.Collections.Generic.List<System.DateTime>;

逆变和协变泛型类型实参

不变量:泛型类型参数不能更改
逆变量:泛型类型参数可以从一个类更改为它的派生类,用in修饰
协变量:可以更改为它的基类,用out修饰
举个栗子

public delegate TResult Func<in T, out TResult>(T arg);
Func<Object,ArgumentException> fn1 = null;
Func<String,Exception> fn2 = fn1;//不需要显示转型

泛型方法

就一句话:优先考虑特化版本!!

约束

约束的作用是限制能指定成泛型实参的类型数量,通过限制类型的数量,可以对那些类型执行更多的操作。
举个栗子:你不指定是引用类型的话,就不能对泛型实参类型的参数进行赋值为null

主要约束

主要约束,我认为就是类型约束,主要是两种

  1. 类型约束public class fan<T> where T : Stream{}T必须是Stream类的相同类或者其子类
  2. 特殊约束where T : class/struct,如果是class约束必须是引用类型,struct约束必须是值类型。如果没有约束为class,就不能将T类型的变量设为null。如果没有约束为struct,就不能new T(),因为引用类型不一定有公共无参构造器。

次要约束

次要约束一般指接口类型,这种约束向编译器承诺类型实参实现了接口,因为能指定多个接口约束,所以类型实参必须实现了所有接口约束。

构造器约束

它向编译器承诺类型实参是实现了公共无参构造器的非抽象类型,不能同时使用struct约束,因为struct默认有共欧诺个无参构造器。

internal sealed class ConstructorConstraint<T> where T : new(){}

其他

  1. 将泛型类型变量设为null是非法的,除非将泛型类型约束成引用类型,但是如果你很想设一个默认值
    T temp = default(T);这是可以的,T是引用类型就设为null,值类型就设为0
  2. 泛型变量相互比较,如果没有约束成引用类型,不能进行比较也就是== 这种,因为值类型相互比较是非法的,除非值类型重载了 ==操作符
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值