C#2.0 泛型详解
使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。
泛型最常见的用途是创建集合类。
.NET Framework 类库在 System.Collections.Generic 命名空间中包含几个新的泛型集合类。应尽可能地使用这些类来代替普通的类,如 System.Collections 命名空间中的 ArrayList,HashTable等。
非泛型类(System.Collections) | 对应的泛型类(System.Collections.Generic) |
ArrayList | List |
Hashtable | Dictionary |
Queue | Queue |
Stack | Stack |
SortedList | SortedList |
使用泛型的建议:
1.如果需要对多种类型进行相同的操作处理,则应该使用泛型。
2。如果需要处理值类型,则使用泛型可以避免装箱拆箱带来的性能开销。
3.使用泛型可以在应用程序编译时发现类型错误,增强程序的健壮性。
4.减少不必要的重复编码,使代码结构更加清晰。
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//使用List<T>替换ArrayList
List<string> ls = new List<string>();
ls.Add("泛型集合元素1");
ls.Add("泛型集合元素2");
ls.Add("泛型集合元素3");
foreach (string s in ls)
Console.WriteLine(s);
//使用Dictionary<Tkey,Tvalue>
Console.WriteLine("Dictinary泛型集合类举例");
Dictionary<string, string> dct = new Dictionary<string, string>();
dct.Add("键1", "值1");
dct.Add("键2", "值2");
dct.Add("键3", "值3");
foreach (KeyValuePair<string, string> kvp in dct)
Console.WriteLine("{0}:{1}", kvp.Key, kvp.Value);
//使用Queue<T>
Console.WriteLine("Queue泛型集合类型:");
Queue<string> que = new Queue<string>();
que.Enqueue("这是队列元素值1");
que.Enqueue("这是队列元素值2");
foreach (string s in que)
Console.WriteLine(s);
//使用Stack<T>
Console.WriteLine("Stack泛型集合类举例");
Stack<string> stack = new Stack<string>();
stack.Push("这是堆栈元素1");
stack.Push("这是堆栈元素2");
foreach (string s in stack)
Console.WriteLine(s);
//使用SortedList<Tkey,Tvalue>
Console.WriteLine("SortedList泛型集合举例");
SortedList<string, string> sl = new SortedList<string, string>();
sl.Add("key1", "value1");
sl.Add("key2", "value2");
sl.Add("key3", "value3");
sl.Add("key4", "value4");
foreach (KeyValuePair<string, string> kvp in sl)
Console.WriteLine("{0}:{1}", kvp.Key, kvp.Value);
Console.ReadLine();
}
}
}
下面我们就来说下,几个泛型集合类的用法:
一.Dictionary
此类在 .NET Framework 2.0 版中是新增的。表示键和值的集合。命名空间:System.Collections.Generic,程序集:mscorlib(在 mscorlib.dll 中)
class TestGenericList
{
static void Main()
{
//声明对象,参数表示,键是int类型,值是string类型
Dictionary<int, string> fruit = new Dictionary<int, string>();
try{
//加入重复键会引发异常
fruit.Add(1, "苹果");
fruit.Add(2, "桔子");
fruit.Add(3, "香蕉");
fruit.Add(4, "菠萝");
//参数错误将引发异常,如下所示
//fruit.Add("5", "aa");
}
catch (ArgumentException)
{
Console.WriteLine("添加错误!!!");
}
//因为引入了泛型,所以键取出后不需要进行Object到int的转换,值的集合也一样
foreach (int i in fruit.Keys)
{
Console.WriteLine("键是:{0} 值是:{1}",i,fruit);
}
//删除指定键,值
fruit.Remove(1);
//判断是否包含指定键
if (fruit.ContainsKey(1))
{
Console.WriteLine("包含此键");
}
//清除集合中所有对象
fruit.Clear();
}
}
Dictionary遍历输出的顺序,就是加入的顺序,这点与Hashtable不同,其它方法如:ContainsKey ,ContainsValue ,Remove 等,使用方法基本一致。
二、List类
注 意:此类在 .NET Framework 2.0 版中是新增的。表示可通过索引访问的对象的强类型列表。提供用于对列表进行搜索、排序和操作的方法。命名空 间:System.Collections.Generic,程序集:mscorlib(在 mscorlib.dll 中),List 类是 ArrayList 类的泛型等效类。
//声明一个泛型类
class TestGenericList
{
static void Main()
{
//声明一个List对象,只加入string参数
List<string> names = new List<string>();
names.Add("乔峰");
names.Add("欧阳峰");
names.Add("马蜂");
//遍历List
foreach (string name in names)
{
Console.WriteLine(name);
}
//向List中插入元素
names.Insert(2, "张三峰");
//移除指定元素
names.Remove("马蜂");
}
}
在 决定使用 List 还是使用 ArrayList 类(两者具有类似的功能)时,记住 List 类在大多数情况下执行得更好并且是类型安全的。如果对 List 类的类型 T 使用引用类型,则两个类的行为是完全相同的。但是,如果对类型 T 使用值类型,则需要考虑实现和装箱问题。
如果对类型 T 使用值类型,则编译器将特别针对该值类型生成 List 类的实现。这意味着不必对 List 对象的列表元素进行装箱就可以使用该元素,并且在创建大约 500 个列表元素之后,不对列表元素装箱所节省的内存将大于生成该类实现所使用的内存。
其实我们也可以自己定义一个泛型类,如下所示:
//声明一个泛型类
public class ItemList<T>
{
void Add(T item) { }
}
class TestGenericList
{
private class ExampleClass { }
static void Main()
{
// 声明一个对象,只能加入int型
ItemList<int> list1 = new ItemList<int>();
//声明一个对象,只能加入Student类型,Student类为自定义类
ItemList<Student> list2 = new ItemList<Student>();
}
}