导航

C#中泛型使用《转》

Posted on 2009-11-26 15:41  kingwangzhen  阅读(535)  评论(0编辑  收藏  举报
先看一个例子:
      
ArrayList list = new Arraylist();
list.Add(
44);

int i1=(int)list(0);
foreach(int i2 in list)
{
   Console.writeLine(i2);
}
装箱和拆箱的操作很容易使用,但是性能损失比较大,如果要是贴袋很多项时更是如此.

System.Collections.Generic命名空间中的LIst<T>类不使用对象,而是在使用时定义类型.
下面的例子中List<T>类的泛型类型定义为int,所以int类型在JIT编译器动态生成的类中使用,不再进行装拆箱的操作:
List<int> list = new List<int>();
list.Add(
44);
int i1 = list[0];
foreach(int i2 in list)
{
  Console.WriteLine(i2);
}

使用List<T>类
List<T>类实现了IList\ICollection\IEnumerable接口
IList接口

表示可按照索引单独访问的对象的非泛型集合。

IsFixedSize 获取一个值,该值指示 IList 是否具有固定大小。
IsReadOnly 获取一个值,该值指示 IList 是否为只读。
Item 获取或设置指定索引处的元素。

 公共方法

  名称 说明
Add 将某项添加到 IList 中。
Clear IList 中移除所有项。
Contains 确定 IList 是否包含特定值。
IndexOf 确定 IList 中特定项的索引。
Insert 将一个项插入指定索引处的 IList
Remove IList 中移除特定对象的第一个匹配项。
RemoveAt 移除指定索引处的 IList 项。

 

ICollection

定义所有非泛型集合的大小、枚举数和同步方法。

 

 公共属性

  名称 说明
  Count 获取 ICollection 中包含的元素数。
  IsSynchronized 获取一个值,该值指示是否同步对 ICollection 的访问(线程安全)。
  SyncRoot 获取可用于同步 ICollection 访问的对象。

公共方法

  名称 说明
  CopyTo 从特定的 Array 索引处开始,将 ICollection 的元素复制到一个 Array 中。

IEnumerable

公开枚举数,该枚举数支持在非泛型集合上进行简单迭代。

下表列出了由 IEnumerable 类型公开的成员。

公共方法

  名称 说明
  GetEnumerator 返回一个循环访问集合的枚举数。

下面的例子使用Recer类作为添加到集合中的元素,以表示赛手,这个类有两个字段,名称和汽车,他们可以用属性访问,在类的构造函数中,应传送赛手和汽车的名称,已设置成员,
public class Racer
{
   
private string name;
   
public string Name
   
{
       
get{return name;}
   }

   
private string car;
   
public String Car
   
{
       
get{return car;}
   }

   
   
public Racer(string name,string car)
   
{
       
this.name=name;
       
this.car=car;
   }

   
public override string ToString()
   
{
       
return name+","+car;
   }

}
使用
    
List<Racer> racer=new List<Racer>();
//添加
racer.Add(new Racer("张三","奇瑞"));
racer.Add(
new Racer("李四","中华"));
racer.Add(
new Racer("王五","神牛"));
  racer.Add(new Racer("王六","神牛"));

..

foreach(Racer r in racer)
{
   Console.WriteLine(r);
}
1.泛型查找
查找所有驾驶神牛的赛车手
使用List<T>类提供了Find()和FindAll()方法,他们的声明:
public T Find(Predicate<T> match);
public List<T> FindAll(Predicate<T> match);
这两个方法都把Predicate<T> 作为参数,Predicate<T> 是一个委托,引用一个谓词方法,谓词返回bool,如果返回true,就匹配一个,如果返回false,就不把元素添加到搜索结果中(不是太懂,接着往下看)Find()方法返回第一个匹配元素,而FindAll()返回谓词匹配的所有元素.

我们使用DrivingCarPredicate()查找开着特定汽车的赛手.这个方法在FindRacer类中定义,DrivingCarPredicate()接收一个Racer对象,比较Tacer对象和汽车在构造函数中设置的汽车,返回true活返回false:
public class FindRacer
{
    
private string car;
    
public FindRacer(string car)
    
{
        
this.car=car;
    }

    
public bool DrivingCarPredicate(Racer racer)
    
{
        
return racer.Car==car;
    }

}
要查找特定的赛车手,应使用Ferrari启动和初始化FindRacer类,因为我们要查找所有赛车手.使用List<T>类的FindAll()方法,实例化一个谓词委托,这个委托接收finder.DrivingCarPredicate方法.FindAll()方法返回一个List<Recer>类型的列表,在使用foreach迭代返回所有赛车手.
FindRacer finder = new FindRacer("神牛");
foreach(Racer recer in racer.FindAll(new Predicate<Racer>(finder.DrivingCarPredicate)))
{
    Console.WriteLine(recer);
}
隐藏的代码:
namespace System


2.执行操作
模板委托不仅可以在Find()/FindAll()方法使用,还可以用于对每个元素执行一些操作.List<T>类提供了ForEach()方法,他使用Action<T>委托对几何中额每个元素执行操作.Action<T>委托的类型是void.
使用ForEach()方法显示
racer.ForEach(delegate(Racer r){Console.WriteLine(r);});
ForEach-----对每个元素执行指定的操作
同样也可以吧前面的FindAll()方法修改为如下:
racer.FindAll(new Predicate<Racer>(finder.DrivingCarPredicate)).ForEach(delegate(Racer r){Console.WriteLine(r);});
对查询出来的每个元素执行输出操作.