大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > C#技巧 > C#集合与泛型

C#集合与泛型

关键词:集合泛型  阅读(736) 赞(16)

[摘要]本文是对集合与泛型的讲解,对学习C#编程技术有所帮助,与大家分享。

集合

物以类聚,相同的东西需要归于一类。我们常常将相互关联的对象组成集合,自然数组成自然数集。同班同学组成班级,诗人做的诗篇,组成诗集。集合中的对象,称为元素(Element)。C#为我们提供一组功能强大的集合类,实现了多种不同类型的集合,我们可以根据实际用途选择恰当的集合类型。下表,是FCL(Framework Common Library)类库为我们提供的部分集合类。

QQ Photo20140823155454

除了Array在System命名空间下,其余的类都位于System.Collections命名空间下。这些类通过直接或间接的继承一些接口,来实现其自身强大的功能。我们之前在项目中用过foreach循环语句,遍历一个集合或数据集。那么是如何foreach是如何实现对集合或数据集的遍历的呢?(与其说是遍历,不如说是迭代。关于迭代概念,大家可以参考一些数据结构书籍的递归算法)。原来FCL提供的集合类,都直接或间接的实现了IEnumerable接口,这个接口声明了一个名为GetIEnumerator()方法。这个方法返回一个继承了IEnumerator接口的类,我们通常将这个类称为迭代器。

//IEnumerable接口
public interface IEnumerable
{
     IEnumerator GetIEnumerator();
}

IEnumerable接口类

//IEnumerator接口
public interface IEnumerator
{
     bool MoveNext();      //获取下一个元素
     object Current{get;}  //获取当前元素
      void Reset();        //将枚举数设置为其初始位置
}

IEnumerator接口类

foreach语句就是通过访问迭代器来获取集合中的元素。ICollection接口也是一个很基础的接口,它继承了IEnumerable接口,并且添加了一个Copy()方法,和一个Count属性以及两个用于同步的属性。

//ICollection接口
public interface ICollection:IEnumerable
{
     void Copy(System.Array array,int index);  //复制到数组
      int Count{get;}                           //元素个数
     bool IsSynchronized;                      //是否同步
    object SyncRoot{get;}                     //用于同步的对象   
}

IList接口、IDictionary接口都继承于ICollection接口。

关于各个集合类的一些方法,大家可以下去自己练习一下。因为,本章主要讲解的是泛型类。其实,在项目中大家更多的会去使用泛型,因为集合存在一个弊端。

集合类的弊端

大家看看下面的代码:

 ArrayList list=new ArrayList();
 lsit.Add(10);         //添加元素
 int n=(int)lsit[0];   //取出元素

因为所有类型都继承于object的类型,所以当我们调用.Add()方法,向集合中添加元素时,系统会默认为object类型。此时,如果添加的元素不是引用类型而是值类型,那么在向集合添加元素时,就会进行装箱操作,将值类型转换为引用类型。同样,在我们读取元素时,需要拆箱操作,将object的类型转换为值类型。这样做,会有三个缺点:

第一、在装箱、拆箱的过程中,可能会造成一定的性能损失。

第二、什么类型的数据都往集合中放,不利于编译器进行严格的类型安全检查。

第三、显示转换类型,降低了程序的可读性。Note(现在计算机越来越快,性能也不是唯一目标了。软件开发成本在于软件维护与升级。所以,提高代码可读性可以降低软件开发成本呢。)

ArrayList   list=new ArrayList();
list.Add(10);
list.Add("hello");
foreach(int element in list)
{
   int n=(int)element;
}

上面这段代码,编译不会出错。运行会出现,因为”hello”不能转换为int类型。现在大家看出集合类的弊端了吧,那么泛型类又有什么地方强于集合呢?其实不难想象,泛型强于集合的地方,一定是集合比较薄弱的地方。集合薄弱的地方就在,集合类的元素类型没有限制。

泛型

泛型与集合的功能基本一致,唯一的不同点在于,泛型类的元素类型受我们控制,是我们指定的类型,而不是万物之祖的object类型。泛型具有一个参数列表<T>,在整个类里用T代表元素类型,T的类型是不确定的,是抽象类型。在我们实例化类时,将抽象类型的元素具体化,具体类型的参数将代替T。看程序:

// 泛型类
 public class  Generic<T>
{
       public void Check()
        {
           Console.WriteLine(this.GetType()); //输出T的类型         
        }     
}


//实例化泛型类
Generic<int>  instanceInt=new Generic<int>();
 instanceInt.Check(); //输出的类型为System.Int32

Generic<String>  instanceString=new Generic<String>();
instanceString.Check();  //输出的类型为System.String;

泛型类中的T,是抽象类型。实例化时,才会将其具体化。例如上面的instanceInt,就是将泛型类中的T,具体化为Int类型。instanceString,就泛型类的T具体化为String类型.我们可以定义泛型类,同意也可定义泛型方法,泛型接口等。看下面的代码:

//泛型类
public static void Swap<T>(ref T a,ref T b)
{
        T t=a;
         a=b;
         b=t;
}

此时的a,b都是抽象的,都是未知的类型。

Static void Main(string[] args)
{
   int x=100;
   int y=200;
  Swap<int> (ref x,ref y);
Console.WriteLine("x={0},y={1}",x,y);
}

我们在调用泛型方法时,将参数具体化了。

C#为我们提供了一些泛型类:

List<T>
Stack<T>
Queue<T>
SortedList<TKey,TValue>
Dictionary<TKey,TValue>

关于他们的一些方法,大家可以查看相关手册。学会通过查看手册来学习编程,是很重的。好了今天的泛型、集合就到这里了。最后,我把作者讲的一句话,给大家分享一下。“实践中磨练编程技能,思考中感悟编程本质”。



相关评论