泛型是 C#2.0 语言和公共语言运行库 (CLR) 中的一个新功能。泛型将类型参数的概念引入 .NET Framework,类型参数使得设计如下类和方法成为可能:这些类和方法将一个或多个类型的指定推迟到客户端代码声明并实例化该类或方法的时候。例如, 通过使用泛型类型参数 T,可以编写其他客户端代码能够使用的单个类,而不致引入运行时强制转换或装箱操作.
使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。
泛型最常见的用途是创建集合类。
.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>来保存一组字符串,比如下面这段代码:
可是有时候,我们要从中获取一个字符串,字符串的内容就是集合中的内容,但是要用逗号隔开,下面的办法可以实现:
上面这条语句,返回的结果应该是下面这个样子:
下面让我们来做个反向工程,从string转换成List<string>
List<string> 定义强类型化string泛型 List<string> a = new List<string>();会有集合的许多操作, List<>是一个泛型对象,实例化后相当于是一个List对象。List对象内部可以聚合若干个(理论上不限制大小)同类型对象,并提供很多方便的方法来提供一些基本操作。可以理解为一个封装好的链表对象。 泛型本身的优点 string[] 就是简单的强类型化数组.,没什么好说的。 |