【C#学习】--泛型

发布时间 2023-04-04 21:07:32作者: 90Red

.1 泛型概述

默认命名空间是

.1.1 特点

泛型是一种程序特性,声明时对类型不作明确规定,使用时必须明确规定且规定后不可再更改

.1.2 应用

泛型集合(常用的List<T>、Dictionary<k,v>都属于泛型集合,而ArrayList和Hashtable则属于非泛型);

泛型方法;

泛型类;

泛型委托(重中之重)

.1.3 实现

以List进行展示,在我们声明List元素数据类型的时候,就已经包含了string、int等多种基础数据类型(声明时范围很宽泛,数据类型多样)

但在使用时,只能从众多数据类型中选取一个,如下面的三个列表,各自只能选择string、int或double,而不能同时使用几种数据类型

 .1.4 补充

关于在概述里提到的非泛型ArrayList和Hashtable(哈希表)

在定义界面可以看到,

相比较泛型所在的System.Collections.Generic命名空间,

ArrayList和Hashtable(哈希表)都属于System.Collections命名空间,

其中ArrayList实现了IList、ICollection、IEnumerable、ICloneable接口,特性是会根据需要动态改变容量

而Hashtable(哈希表)实现了IDictionary、ICollection等接口,特性是键值对基于键的hashcode进行组织

ArrayList可以调用的Add()方法的参数列表中的数据类型为object,这也就说明了ArrayList类的对象可以是object下包含的各种具体数据类型

 虽然这种方式对于用户添加不同类型的元素很方便,但对于数据本身来说是非常不安全的,在开发过程中我们应该尽可能减少这种不可控状况的存在

除此之外,还这种方式涉及拆装箱的问题

装箱:将值类型的元素,放到集合中会被转换成object类型(如上图Add方法所示:value -> object),这一过程成为装箱

拆箱:将一个集合中的元素取出,但这个元素本质是值类型,因此必须强制类型转换

一旦涉及拆装箱,由于反复的类型转换,在存储大量数据的情境中,性能会受到明显的影响,

非泛型集合的弊端由此体现,并且在实际应用中,在一个集合中不对数据类型进行限定属于罕见情况,这就进一步缩减了非泛型集合的优势,

用户的主流需求:不希望在一个容器中添加不同类型的数据,但希望容器能根据我们的需求,随时决定能够添加哪一种具体类型的数据

即容器内存储数据的类型在某一个时间点应该是确定的但又可以随时更改(要么是A,要么是B,想改成A或者B都可以,但是A和B在同一时间不允许被容器同时接受——>因此如概述中说的那样,对于类型声明时不作明确规定,使用时必须明确规定)

因此后面推出了泛型。

由此,在上面的泛型集合和非泛型集合的对比上,反而有种“泛型正统并不在泛型集合而在非泛型集合”的感觉,从非泛型集合身上感受到的才是从声明到使用自始至终唯一不变的自由(题外话)

.2 泛型方法

.2.1 诞生意义

已知一个现有方法A,当我们需要一个与A相比实现逻辑完全相同,仅仅是参数列表里的参数所属数据类型不同的方法B时,如何创建?

传统方式

 在面对多种数据类型的时候,这种方式未免过于死板笨重,为了改进,我们可以定义泛型方法

 从左到右分别对方法的返回值类型、被方法用于运算的参数的数据类型及参数列表里各个参数的数据类型进行了泛型处理

(逻辑上应该是先确定方法所使用的参数类型为T,由此在方法名FFC后用<T>进行泛型处理,然后参数列表里的各个参数也应该随之属于T数据类型,既然参与运算的参数都是T类型,那么最终的返回值也应该是T类型)

这里虽然报错了但是问题在于我们对参数进行泛型处理后系统无法确定此时的数据类型一定能参与+运算,如果要继续修改则要重写+的运算方法,这里仅用于演示如何利用泛型优化上面的情境

.2.2 实现

分别使用泛型对类的成员类型、方法的参数类型、方法的返回值类型进行处理

 基于上面的泛型类声明一个测试方法