C#学习第三周-泛型-
泛型
普通方法实现加法:
泛型方法实现加法:
public static void Add<T>(T t1,T t2)
{
if(t1 is int)
Console.WriteLine(int Parse(t1.tostring())+int.Parse(t2.ToString()));
}
if(t1 is float)
{
Console.WriteLine(float.Parse(t1.ToString())+float.Prase(t2.ToString()));
}
}
泛型实现交换
C#中的泛型能够将类型作为参数来传递,即在创建类型时用一个特定的符号如T来作为一个占位符,代替实际的类型,等待在实例化时再用一个实际的类型来代替:
public static void Swap<T>(ref T value0,ref T value1)
{
T temp = value0;
value0 = value1;
value1 = temp;
}
使用泛型可以重用代码,保护类型的安全以及提高性能
降低强制转换或装箱操作的成本和风险
可以对泛型参数进行限定以访问特定数据类型的方法
泛型方法
泛型方法就是使用泛型类型参数声明的方法,当方法中存在某些参数的类型不明确时候就可以使用泛型方法。未知具体类型的参数就使用泛型类型参数代替。
**访问修饰符 返回值类型 方法名<泛型类型列表>(参数列表){方法体}**
void Test<T,U>(T p1,U p2)
{
}
泛型参数
泛型参数可以有多个
泛型类型参数可以是翻译器识别的任何数据类型
泛型类型参数命名需要遵守命名规则:
1.使用描述性名称命名泛型类型,并且使用T作为前缀
2.单个字母名称完全可以让人了解其表示的含义使用单个大写字母命名
泛型参数约束
为了防止传入的类型导致方法运行出错,可以对泛型进行一定的约束
约束关键词:Where
- where T:struct :表示泛型T是值类型(小数、整数、char、bool、struct)
- where T:class :表示泛型是引用类型
- where T:new() :表示这个泛型具有一个无参数的构造方法,如果有多个约束,new()必须放在最后
- where T:基类名 :表示这个泛型是该基类或者其派生类
- where T:接口名 :表示泛型是为了实现该接口的类型
- where T:U :为T提供的类型参数必须是为U提供的参数或派生自为U提供的参数。
通过约束类型参数,可以增加约束类型及其继承层次结构中的所有类型所支持的允许操作和方法调用的数量。
可以对多个参数应用约束,也可以对同一参数进行多个约束。
void Test<T,U>(T p1 ,U p2)where U :struct
where T :Computer,new()
{
}
泛型方法的调用
public static string CombineToString<T>(T value1,T value2)
{
return value1.ToString()+value2.ToString();
}
public static void Main(string[] args)
{
Console.WriteLine(CombineToString<int>(234,56));
}
调用方法时,有些时候泛型类型可以忽略
Console>WriteLine(CombineToString(234,56));
泛型方法的泛型重载
void DoWork(){}
void DoWork<T>(){}
void DoWork<T,U>(){}
泛型类与泛型接口
interface ITest<T>
{
T getTest(T t);
}
class Person<T>
{
T name;
}
//--------
class Person
{}
class Person<T,U>
{
T name;
T age;
}
//**类的泛型重载**
Person<string> xiaoming = new Person<string>();
练习
定义接口IUSB,该接口当中定义了数据读取的方法ReadData();定义抽象类存储设备MemoryDevice,该抽象类MemoryDevice实现了IUSB接口,并且当中有抽象方法Description,用于不同存储设备插入电脑自我描述。存储设备分为固态硬盘SolidStateDisk,机械硬盘HardDisk,U盘UDisk三种。定义电脑类,该类包含功能:插入硬件设备。
数组的局限性
数组只能存储相同类型的数据
数组不能动态的扩展长度
集合的概念
集合的定义
集合原本是数学上的一个概念,表示一组具有某种性质的数学元素,引用到程序设计中表示一组具有相同性质的对象。集合好比容器,将一系列相似的组合一起,是一个特殊的类,和数组一样,可以通过索引访问集合成员,也可以通过”键”来访问,与传统数组不同的是,集合的大小可以动态调整,可以在运行时添加或删除元素。
集合的类型
集合可分为两类:泛型集合与非泛型集合
泛型集合类一般位于System.Collections.Generic名称空间,
非泛型集合类位于System.Collections名称空间
此外,System.Collections.Specialized名称空间中也包含一些有用的集合类。
非泛型集合
下面是各种常用的System.Collections命名空间
泛型集合
下面是各种常用的System.Collections.Generic命名空间的类
动态数组 ArrayList
- 动态的增加和减少元素
- 实现了ICollection和IList和IEnumerable接口
- 灵活的设置数组大小
- 不安全的集合类型
- 其元素为值类型时,效率不高(装箱和拆箱耗性能)
ArrayList常用方法与描述
List 泛型动态数组
- List类是ArrayList类的泛型等效类
- 同样实现了IList接口,IEnumrator接口和ICollection
- 与ArrayList不同的是,声明集合时需要声明集合内部的数据类型,即T的类型
- 安全的集合类型
- 某种情况时,在处理值类型时其处理速度比ArrayList快得多
LIst常用方法与描述
常见集合和列表实现接口
练习
利用ArrayList或者是List<>做一个小型的学生管理系统,如添加学生,查询学生等功能
堆栈-Stack
- 后进先出(LIFO)的一种数据结构,本质上堆栈也是一种线性结构
- 线性结构的特点:即每个节点有且只有一个前驱结点和一个后续结点
- 随着像Stack中添加元素,容量通过重新分配按需自动增加
- 可以接受null作为有效值
- 允许重复的元素
- 不安全的数据结构
- 其泛型为Stack
Stack成员介绍 常用方法与描述
队列-Queue
- 先进先出(FIFO)的一种数据结构
- 可以接受null作为有效值
- 允许重复的元素
- 不安全的数据结构
- 其泛型为Queue
Queue常用方法与描述
哈希表 HashTable
- 处理和表现类似key-value的键值对的集合
- Key和Value都是object类型
- key值必须唯一,区分大小写
- Value可以是值类型变量,也可以是对象
HashTable常用方法与描述
Dictionary<K,V> 字典
- 处理和表现类似key-value的键值对的集合
- Key和Value的类型由泛型指定
- key值必须唯一,区分大小写
- Value可以是值类型变量,也可以是对象