泛型是 2.0 版 C# 语言和公共语言运行库 (CLR) 中的一个非常重要的新功能。在此之前进行数据转化时候需要进行装箱与拆箱操作。我们知道装箱与拆箱需要消耗很大性能,泛型的引用主要优点是性能。
在学习泛型之前我们先了解一下值类型,引用类型以及装箱,拆箱。
值类型存储在栈上,引用类型存储在堆上。C#的类是引用类型,结构是值类型。.NET很容易把值类型转换成引用类型,例如int类型的值可以任意赋值给一个对象,反之,任意一个装箱后的值类型可以进行转换成引用类型,这个过程我们称之为拆箱操作,拆箱时,需要进行类型的强制转换。
下面我们拿ArrayList为例来说明一下拆箱与装箱:
static void Main(string[] args)
{
ArrayList list = new ArrayList();
//ArrayList.Add(object value)方法,可以看出传入的参数为object类型
list.Add(10);//这里传入int类型10,则进行装箱操作
//如果这时候我们想获取这个int类型
//int value = list[0];//如果这里不做强转则会报出异常:无法将类型“object”转成“int”,需要进行强转。这里也可以看出int类型存入list后进行了装箱操作
int value = (int)list[0]; //如果需要读取list保存的原来的int值,则需要进行拆箱操作
}
后来C#加入了泛型T,如下:
System.Collections.Generic名称空间中的List<T>类不使用对象,而是在使用时定义类型。实例如下:
class Program
{
static void Main(string[] args)
{
List<int> list1 = new List<int>();
List<string> list2 = new List<string>();
List<Student> list3 = new List<Student>();
list1.Add(1);
list1.Add(2);
list1.Add(3);
foreach(int i in list1)
{
Console.WriteLine(i);
}
list2.Add("Hello");
list2.Add("Word");
list2.Add("!");
string str = string.Empty;
foreach (string item in list2)
{
str += item + " ";
}
Console.WriteLine(str);
Student std1=new Student();
std1.Id=1;
std1.Name="张三";
list3.Add(std1);
Student std2 = new Student();
std2.Id = 2;
std2.Name = "李四";
list3.Add(std2);
Student std3 = new Student();
std3.Id = 3;
std3.Name = "王五";
list3.Add(std3);
foreach (Student item in list3)
{
Console.WriteLine("学号:{0};姓名:{1}", item.Id,item.Name);
}
Console.ReadLine();
}
}
public struct Student
{
public int Id { get; set; }
public string Name { get; set; }
}
泛型使用的时候指定类型即可避免了装箱拆箱的操作,大大增加了性能。