zoukankan      html  css  js  c++  java
  • IList, ICollection ,IEnumerable AND IEnumerator in C#

      IList, ICollection ,IEnumerable 很显然,这些都是集合接口的定义,先看看定义:

     1 // 摘要:
     2     //     表示可按照索引单独访问的对象的非泛型集合。
     3     [ComVisible(true)]
     4     public interface IList : ICollection, IEnumerable
     5     {
     6         
     7         bool IsFixedSize { get; }
     8         
     9         bool IsReadOnly { get; }
    10        
    11         object this[int index] { get; set; }
    12         
    13         int Add(object value);
    14         
    15         void Clear();
    16         
    17         bool Contains(object value);
    18         
    19         int IndexOf(object value);
    20         
    21         void Insert(int index, object value);
    22         
    23         void Remove(object value);
    24         
    25         void RemoveAt(int index);
    26     }
     1 // 摘要:
     2     //     定义所有非泛型集合的大小、枚举数和同步方法。
     3     [ComVisible(true)]
     4     public interface ICollection : IEnumerable
     5     {        
     6         int Count { get; }
     7         
     8         bool IsSynchronized { get; }
     9         
    10         object SyncRoot { get; }
    11 
    12           void CopyTo(Array array, int index);
    13     }
    1 // 摘要:
     2     //     公开枚举数,该枚举数支持在非泛型集合上进行简单迭代。
     3     [ComVisible(true)]
     4     [Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
     5     public interface IEnumerable
     6     {
     7         // 摘要:
     8         //     返回一个循环访问集合的枚举数。
     9         //
    10         // 返回结果:
    11         //     一个可用于循环访问集合的 System.Collections.IEnumerator 对象。
    12         [DispId(-4)]
    13         IEnumerator GetEnumerator();
    14     }

     可以看出,所有集合接口的祖宗是IEnumerable

         此接口只有一个方法 GetEnumerator()。是为了实现迭代器模式设计的接口。所有继承了IEnumerable的类,要使用foreach迭代器时,就需要使用该方法。因此也只有实现了该接口的类才可以使用foreach。

         ICollection继承自IEnumerable,IList继承自ICollection

         这两个接口都是为了给集合提供一些公用的方法。只是分了两个层次,IList比ICollection多几个方法,增加,移除成员。可以简单理解为:ICollection主要针对静态集合;IList主要针对动态集合。

          IList 是 ICollection 接口的子代,并且是所有非泛型列表的基接口。IList 实现有三种类别:只读、固定大小和可变大小。无法修改只读 IList。固定大小的 IList 不允许添加或移除元素,但允许修改现有元素。可变大小的 IList 允许添加、移除和修改元素 (IList中的  IsFixedSize { get; }  和  bool IsReadOnly { get; })

      IList,ICollection,IEnumerable 在命名空间System.Collections中。

          关于System.Collections空间

          System.Collections命名空间包含可使用的集合类和相关的接口,提供了集合的基本功能。     

       该命名空间下的.NET非泛型集合类如下所示:

          — System.Collections.ArrayList:数组集合类,使用大小可按动态增加的数组实现Ilist接口。 
          — System.Collections.BitArray:布尔集合类,管理位值的压缩数组,该值为布尔值。
          — System.Collections.Queue:队列,表示对象的先进先出集合。
          — System.Collections.Stack:堆栈,表示对象的简单的后进先出集合。
          — System.Collections.Hashtable:哈希表,表示键/值对的集合,这些键/值对根据键的哈希代码进行组织
          — System.Collections.SortedList:排序集合类,表示键/值对的集合,这些键和值按键排序并可按键和索引访问。

        该命名空间下的.NET非泛型接口如下所示:

          — System.Collections.ICollection:(继承于IEnumerable)定义所有集合的大小,枚举器和同步方法,可以获取集合中项的个数,并能把项复制到一个简单的数组类型中。
          — System.Collections.IComparer:比较两个对象的方法
          — System.Collections.IList:(继承于IEnumerable 和 ICollection)表示可按照索引单独访问一组对象,提供集合的项列表,并可以访问这些项。
          — System.Collections.IDictionary:(继承于IEnumerable 和 ICollection)表示键/值对的集合
          — System.Collections.IDictionaryEnumerator:枚举字典的元素
          — System.Collections.IEnumerator:支持在集合上进行简单迭代,可以迭代集合中的项。支持在非泛型集合进行简单迭代。

      IList<T>,ICollection<T>,IEnumerable<T> 在System.Collections.Generic 命名空间中。     

                    System.Collections.Generic是.net中的泛型集合 

        IList<T>,ICollection<T>,IEnumerable<T> 是2.0引入泛型以后新增的。主要是提高重用性与类型安全。   IEnumerable<T>继承自IEnumerable,ICollection<T>继承自IEnumerable<T>,List<T>继承自ICollection<T>   因此可以完全使用泛型接口,而放弃使用ICollection和IList。泛型接口提供了更好的类型安全和编译时的检验。       补充:  IEnumerable<T>和IEnumerable都只有一个方法。ICollection<T>和ICollection的结构是不一样的。ICollection<T>比ICollection多几个方法。它包含了几个IList中的几个方法。也许是对以前的改进。

     

        IEnumerable 和 IEnumerator

     如果一个类实现了IEnumerator,也就是实现Current属性,MoveNext方法,Reset方法。只要实现这些方法,这个类就可以用foreach这种语法了。 

          IEnumerable接口主要实现了GetEnumerator方法,该方法返回一个IEnumerator。一个类实现IEnumerable接口后,调用foreach语法的时候,会自动的调用GetEnumerator方法,然后在这个IEnumerator中遍历。  所以只要实现两者之中任意一个接口,就可以用foreach语法了。但是本质上都是对IEnumerator做foreach,只是一个是直接,一个是间接。

          代码说明:

      比如类Test,实现了IEnumerable,那么下面的代码

        foreach (Test  t  in ts)

        {     ... } 

      说明代码就功能上等同于下面的代码

        IEnumerator td= ts.GetEnumerator(); 

        while (td.MoveNext()) 

        {     

          t = (Foo)td.Current()    

          ...  

        }   

        如果一个类,同时实现了IEnumerator<T>,IEnumerable<T>,那么就是糟糕的设计 因为用foreach语法的时候,会先调用IEnumerable的GetEnumerator方法。

     

     

      IList<T> 和List<T>

      首先IList 泛型接口是 ICollection 泛型接口的子代,并且是所有泛型列表的基接口。
      它仅仅是所有泛型类型的接口,并没有太多方法可以方便实用,如果仅仅是作为集合数据的承载体,确实,IList可以胜任。
      不过,更多的时候,我们要对集合数据进行处理,从中筛选数据或者排序。这个时候IList就爱莫能助了。
      1、当你只想使用接口的方法时,ILis<>这种方式比较好.他不获取实现这个接口的类的其他方法和字段,有效的节省空间.(既然子类是继承父类的子类又有自己的属性和方法,那么子类NEW出来后这些都应该有而且必须有的,不论放在父类的变量里面还是自身类型的变量里面,不然的话向上转型后再向下转型数据就会丢失喽,太可怕了!)
      2、IList <>是个接口,定义了一些操作方法这些方法要你自己去实现,List <>是泛型类,它已经实现了IList <>定义的那些方法
      IList ilist=new List ();
      List list=new List ();
      这两行代码,从操作上来看,实际上都是创建了一个List对象的实例,也就是说,他们的操作没有区别。
      只是用于保存这个操作的返回值变量类型不一样而已。
      那么,我们可以这么理解,这两行代码的目的不一样。
      List List11 =new List ();
      是想创建一个List,而且需要使用到List的功能,进行相关操作。
      而IList IList11 =new List ();
      只是想创建一个基于接口IList的对象的实例,只是这个接口是由List实现的。所以它只是希望使用到IList接口规定的功能而已。

     

      如果一个方法的返回值是IEnumerable<T> ,必须在方法后面使用.ToList()方法才能得到一个集合数据

         List<XElement> grandchildElements = xlsElement.XPathSelectElements("//model").ToList();

      使用.ToArray()方法,就会创建一个数组数据

        XElement[] elements = xlsElement.Descendants(nodeName).ToArray();

      集合数据要用foreach来遍历,而数组数据可以使用下标操作。

  • 相关阅读:
    jQuery 基本选择器
    JavaScriptif while for switch流程控制 JS函数 内置对象
    JavaScrip基本语法
    数据库 存储引擎 表的操作 数值类型 时间类型 字符串类型 枚举集合 约束
    数据库基础知识 管理员 用户登录授权的操作
    粘包的产生原理 以及如何解决粘包问题
    socket TCP DPT 网络编程
    2018年年终总结
    Android技术分享
    No accelerator found
  • 原文地址:https://www.cnblogs.com/wushuaiyi/p/4653574.html
Copyright © 2011-2022 走看看