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>();
}
}
泛型的用法还有很多种,如泛型方法,泛型委托,泛型接口等。
泛型,就是说这个容器内只能装 <>里面的类型。
List <String>中List中装的是String
List <List <String>>中装的是List
以前的List,好比是个箱子,你可以把相近的东西扔在里面
泛型好比是个收纳箱,不但可以放对象,还要在上面标明箱子里面放什么东西
泛形的使用,因为list中的元素添加的是String类型的,使用泛形代表你list中所有元素都为String类型
说白了..就是LIST里再嵌套LIST...
<>使用了泛型,就是告诉JVM该LIST里面装的是什么类型的东西.
List <String>中List中装的是String
List <List <String>>中装的是List,里面的LIST装的是String.
恩恩,就是泛型没错啊,声明数组的时候, <>里面写的就是规定好了的数据类型或类,如:List <String>就表示这个里面只能装String类型的东东,装不进其他的,至于List <List <String>>嘛,就是,先来一个装String类型的List,就是里面那个,再来一个装List的List,就是外面那个,Over!
用泛型的好处是显而易见的性能问题
先看看不用泛型的时候:
List list=new ArrayList();
//list.add();
//填充list
for(int i=0;i <list.size();i++){
User user=(User)list.get(i);
}
每次取出来的时候都要把Object强转成User类型,据Sun的技术人员说,这样会损失不少性能
用了泛型之后:
List <User> list=new ArrayList <User>();
//list.add();
//填充list
for(int i=0;i <list.size();i++){
User user = list.get(i);
}
代码变得健壮了不说,而且性能的提高也是非常可观的。
我们在开发中经常会用List<string>来保存一组字符串,比如下面这段代码:
studentNames.Add("John");
studentNames.Add("Mary");
studentNames.Add("Rose");
可是有时候,我们要从中获取一个字符串,字符串的内容就是集合中的内容,但是要用逗号隔开,下面的办法可以实现:
上面这条语句,返回的结果应该是下面这个样子:
下面让我们来做个反向工程,从string转换成List<string>
List<string> newStudentNames = new List<string>(result.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries));
foreach (string s in newStudentNames)
{
System.Diagnostics.Debug.WriteLine(s);
}
List<string> 定义强类型化string泛型 List<string> a = new List<string>();会有集合的许多操作, List<>是一个泛型对象,实例化后相当于是一个List对象。List对象内部可以聚合若干个(理论上不限制大小)同类型对象,并提供很多方便的方法来提供一些基本操作。可以理解为一个封装好的链表对象。 泛型本身的优点 string[] 就是简单的强类型化数组.,没什么好说的。 |