泛型作为参数_C#笔记~泛型

一、引入泛型

在实际开发中,常常会出现重复代码的问题,例如。

e3e952dab3e82f82588557cd49a407c6.png
a4acf290774c3a07c92c85463fccdde6.png

运行结果

这里的三个方法,使用不同的类型干了同样的事情。作为一个有追求的程序员,是绝不允许这样的事情发生的。我们观察发现,这三个方法除了方法名称和参数类型不同,方法体一模一样。我们知道object类型是一切类型的基类,根据里氏替换原则,子类对象可以赋值给父类,也即是说,可以使用object类型替换具体的类型。于是有基类版本的通用方法,且看下图。

c33bdbd5c74edbfb8a703b6c11a00408.png
b875ced5987576411b99c68981154969.png

运行结果

代码重复的问题就这么轻松搞定,但是其中存在的问题却不容忽视。

1.对于值类型(这里的int),发生了装箱、拆箱问题,从栈Copy到堆,从堆写到栈,都是多余的操作,产生性能损耗

2.object类型是一切类型的基类,那么这个方法对所有类型都适用,这样容易引发类型安全问题。

那么,有没有一种方式,既可以解决代码重复问题,又可以避免出现上诉问题呢?

答案是:泛型。

二、什么是泛型

泛型让我们可以编写一个可以与任何数据类型一起工作的类或方法。可以简单地理解为:泛型是类型的模板。

泛型不是一种语法糖,而是.NetFramework 2.0推出的新语法,是框架升级支持的新功能。

三、声明和使用泛型

ed9aea76326a5574d72320ec4e67ba86.png

泛型方法

963746d10086361868c11744cf384659.png

运行结果

泛型使用尖括号和泛型名称构成:,使用时尖括号内的T需替换为实际类型,也可以不带尖括号而由类型推断判断实参的类型。

四、泛型原理

在声明泛型时,类型是未确定的,在调用泛型时,必须指定实际类型。这种在定义时未确定类型而使用时确定类型的方式,可以称为延迟声明。延迟声明体现了推迟一切可以推迟的设计思想。

4dd657425cb7c212ad5c817c000febc0.png

五、性能比较

f2d2eb8bdc1db09e96b36ff4b7815972.png

循环1亿次

70ef4dcec7d643b9b78324f2b0461efa.png

运行结果

多次运行后发现,普通方法和泛型方法的耗时相差不大,而object方法因为装箱耗时是其他两种方法的倍数。

六、泛型类、泛型接口、泛型委托

前面我们讲解的都是泛型方法,其实除了泛型方法,还有泛型类、泛型接口、泛型委托。

7adacc3474c60325e82afa39ceff5c98.png

泛型类

dd36685b984bdb4376cb94c33d338b0b.png

泛型接口

e3b54bee4404ea6846fbd7cd1992195b.png

泛型委托

对于泛型类和泛型接口,如果其他类继承或实现了它,要求这个类必须指定具体的类型,或者不指定类型但此类也是泛型类。

七、泛型约束

在第六点我们已经使用了泛型约束,请看上图where部分。泛型约束是为类型安全而设计的,它有如下几种约束:

e11bf0d4189a3fc622b729cd8fb3e3a2.png

结构约束。值类型,必须在其他约束之前

e41dcbf5b955e3d5372942a34ffd208f.png

类约束。引用类型,必须在其他类型约束之前

dcb2f07271394fc079215536823a92c6.png

无参数构造函数约束。与其他约束使用时,必须放在最后

da99b702f745e34dc7124c18b762b217.png

基类约束。基类或派生类,该基类必须是可继承的

44ee6c6936c3f58fab832fe7ea20bc3d.png

接口约束。可以指定多个接口约束,类型必须实现该接口

八、协变(out)、逆变(in)

ef8859de308d1a6d585a0e610267bebd.png

使用泛型之后,我们发现基类和子类的泛型并没有继承关系,但实际业务中,他们还是父子关系。

为解决上述问题,引入了协变、逆变。

1.协变,让赋值表达式右边可以用子类

协变只能修饰返回参数。为什么不能修饰传入参数呢?因为父类赋值给子类。

2eb077ca8b6e578f65ec4b35aa077c15.png
6bed2823a6fa5469ea13d64994fb1440.png

2.逆变,让赋值表达式右边可以用父类

逆变只能修饰传入参数。

9c33c31867bb4c55ee5d3da84b715190.png
07ce2b2d8cbe88953e406b10b732160f.png

3.协变逆变只能用于接口、委托。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值