泛型是.NET Framework2.0新增的一个特性,在命名空间System.Collections.Generic,包含了几个新的基于泛型的集合类,官方建议.net 2.0 及更高版本的应用程序使用新的泛型集合类,而不使用非泛型集合类,例如ArrayList。
泛型类是引用类型,主要是引入了类型参数这个概念。泛型作用:代码重用、类型安全、性能更佳。
类型参数一般放在所定义的类、方法、接口等标识符后面,并且包含在“<>”里面。当类型参数里只有单个泛型类型时,考虑使用T作为泛型类型名,如class Note。可以一次性定义多个泛型类型,如泛型方法Swap<T,U,Z>三个泛型类型。
装箱:是指从值类型转换成引用类型
拆箱:是指从引用类型转换成值类型
【ArrayList】是一个极为方便的集合类,可以用于存储任何引用或值类型。但是缺点也很明显,第一个缺点是编译的时候不会检查类型
至于ArrayList第二个缺点就是装箱拆箱的时候回造成性能的损失
【ArrayList 示例】
System.Collections.ArrayList list1 = new System.Collections.ArrayList();
list1.Add(3);
foreach (int item in list1)
{
Console.WriteLine(item.ToString());
}
【List泛型示例】
//创建集合对象
List<int> list = new List<int> ();
list.Add(100);
list.Add(200);
list.Add(300);
list.AddRange(new int[]{1,2,3}); //添加数据集合
list.AddRange(list); //添加集合
//list.Clear(); //清空
int[] nums=list.ToArray(); // //list集合转为一个数组
List<int> listTwo = nums.ToList(); //将数组转化为一个相应类型的集合
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine(list[i]);
}
Console.Read();
输出结果
常见的泛型类型
在泛型类型的定义中,出现的每个T(一个占位变量而已叫别的名字也行)在运行时都会被替换成实际的类型参数。下面是一些基础的泛型类型
泛型类、泛型接口、泛型方法、泛型数组、泛型委托、泛型结构
1、泛型方法: 交换两数的值
static void Main(string[] args)
{
int a = 1;
int b = 2;
SwapGeneric(ref a,ref b);
Console.WriteLine($"a={a}b={b}");
}
//交换两个变量的方法
public static void SwapGeneric<T>(ref T a, ref T b)
{
T temp;
temp = a;
a = b;
b = temp;
}
2、泛型类
泛型类封装不属于特定具体数据类型的数据或操作。泛型类最常见的就是泛型集合类,如链表、哈希表、堆栈、队列、树等。对于集合的操作,如从集合中添加、移除、排序等操作大体上都以相同方式进行的,与所存储数据类型无关,即可使用泛型技术。
在泛型类中使用的数据类型,可以是泛型类型也可以是普通的。一般规则是,类中使用的泛型类型越多,代码就会变得越灵活,重用性就越好。但是要注意,类中如果有太多的泛型类型也会使其他开发人员难以阅读或理解该类。
【典型的泛型类】
.Net框架类库中,System.Collections.Generic和System.Collections.ObjectModel命名空间中,分别定义了大量的泛型类和泛型接口,这些泛型类多为集合类,因为泛型最大的应用正体现于再集合中对于不同类型对象的管理。
泛型类 | 说明 |
---|---|
List | 对应于ArrayList集合类,可以动态调整集合容量,通过索引方式访问对象,支持排序、搜索和其他常见操作。 |
SortedList<TKey,TValue> | 对应于SortedList集合类,表示Key/Value对集合,类似于SortedDictionary<TKey,TValue>集合类,而SortedList在内存上更有优势。 |
Queue | 对应于Queue集合类,是一种先进先出的集合类,常应用于顺序存储处理。 |
Stack | 对应于Stack集合类,是一种后进先出的集合类。 |
Collection | 对应于CollectionBase集合类,是用于自定义泛型集合的基类,提供了受保护的方法来实现定制泛型集合的行为Collection的实例是可修改的 |
Dictionary<TKey,TValue> | 对应于Hashtable集合类,表示Key/Value对的集合类,Key必须是唯一的,其元素类型既不是Key的类型,也不是Value的类型,而是KeyValuePair类型。 |
3、泛型结构体
struct Point<T> {
public T X;
public T Y;
}
Point<int> a =newPoint<int>();
a.X=1;
a.Y=2;
Console.WriteLine("{0},{1}",a.X,a.Y);
4、泛型委托 (泛型委托使用的时候不是很多,要慎用)
=====================【泛型类型参数约束】 =======================
作用:筛选类型参数。在使用泛型的代码中如果违反了某个约束不允许的类型来实例化则会产生编译错误,类型参数的约束是使用关键字where。下面列出了6中类型的约束
1> where T: struct
类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型。
2> where T : class
类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型。
3> where T:new()
类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new() 约束必须最后指定。
4> where T:<基类名>
类型参数必须是指定的基类或派生自指定的基类。
5>where T:<接口名称>
类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。