1、泛型概念
定义:泛型是通过参数化类型来实现在同一份代码上操作多种数据类型的技术
利用“参数化类型” 将类型抽象化,从而实现灵活的复用。
泛型是C#2.0以后的一种新语法,不是语法糖
为什么用泛型
1、减少装箱和拆箱,提高运行效率
List<int> list = new List<int>();
2、类型安全
List<int> list = new List<int>();
3、代码重用
public static bool AreEqual<T>(T value1, T value2)
{ return value1.Equals(value2); }
bool result = AreEqual<string>("A", "A");
bool result = AreEqual<int>(5, 3);
泛型的优点
1. 泛型增强了代码的可读性
2. 泛型有助于实现代码的重用、保护类型的安全以及提高性能。
3. 我们可以创建泛型集合类。
4. 泛型实现了类型和方法的参数化
5. 我们还可以对泛型类进行约束以访问特定数据类型的方法。
6. 关于泛型数据类型中使用的类型的信息可在运行时通过使用反射获取。
T:struct
类型参数必须是值类型。可以指定除Nullable以外的任何值类型。有关更多信息,请参见使用可空类型(C#编程指南)。
T:class
类型参数必须是引用类型。包括任何类/接口/委托或数组类型。
T:new()
类型参数必须具有无参数的公共构造参数。当与其他约束一起使用时,new()约束必须最后指定。
T:<基类名>
类型参数必须是指定的基类或派生自指定的基类子类。
T:<接口名称>
类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的
泛型方法
在C#2.0中,方法可以定义特定于其执行范围的泛型参数。
泛型方法,提供了更加多变的灵活性。泛型方法可以存在于泛型类,也可以在于非泛型类中。你可以将类型参数作为某个方法的参数、返回值、或者局部变量,该类型参数可能并不被整个类所需要,而更明确的用于某个方法。
泛型接口
泛型接口定义
public interface IFace<T>
{ T SayHi(); void SayHello(T msg); }
.Net Framework 常见的泛型接口
在.NET 框架类库中的泛型接口,还包括 ICollection<T>、Icomparable<T>、Icomparer<T>、IDictionary<Tkey,TValue>等等。
常见的泛型集合类
List<T> 对应ArrayList集合类
SortedList<TKey, TValue> 对应SortedList集合类
Queue<T> 先进先出的集合类
Stack<T> 后进先出的集合类
Collection<T> 自定义泛型集合的基类
Dictionary<TKey, TValue> 对应于Hashtable集合类
泛型缓存
类中的静态类型,无论被使用多少次内存中都只存在一个。静态构造函数只会执行一次。
在泛型类中,T类型不同,每个不同的T类型,都会产生一个不同的副本,所以会产生不同的静态属性、静态构造函数。
注意: 1.泛型缓存比字典缓存效率高。 2.泛型缓存不能主动释放。
2、队列
队列是一个先进先出的对象集合
Count:获取Queue中包含的元素个数
Clear():从ueue中移除所有元素
Contains(object obj):判断某个元素是否在Queue中
Dequeue():移除并返回在Queue在末尾添加一个对象
Enqueue(object obj) :向Queue的末尾添加一个对象
ToArray():复制Queue到一个新的数组中
TrimToSize():设置容量为Queue中元素的实际个数
ConcurrentQueue<T>队列是一个高校的线程安全的队列,是.Net Framework 4.0,System.Collections.Concurrent命名空间下的一个数据结构。
3、栈
栈是一种"后进先出"(Last in First Out,LIFO)的线性结构。
栈就像某种只有单个出入口的仓库,每次只允许一件件地往里面退货物(入栈),然后一件件往外获取(出栈),不允许从中间放入或者抽出货物。
栈中插入数据元素的过程称为入栈(push)
删除元素的过程称为出栈(pop)
栈和队列是两种特殊的线性表。
它们的数据元素之间具有顺序的逻辑关系,都可以采用顺序存储结构和链式存储结构。
线性表的插入和删除操作不受限制,可以在任意位置进行。
栈的插入和删除操作只允许在表的一端进行。
队列的插入和删除操作则分别在表的两端进行。