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. }

IList

  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. }

ICollection

  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(-)]
  13. IEnumerator GetEnumerator();
  14. }

IEnumerable

可以看出,所有集合接口的祖宗是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

  1. // 摘要:
  2. // 支持对非泛型集合的简单迭代。
  3. [ComVisible(true)]
  4. [Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
  5. public interface IEnumerator
  6. {
  7. // 摘要:
  8. // 获取集合中的当前元素。
  9. //
  10. // 返回结果:
  11. // 集合中的当前元素。
  12. object Current { get; }
  13.  
  14. // 摘要:
  15. // 将枚举数推进到集合的下一个元素。
  16. //
  17. // 返回结果:
  18. // 如果枚举数成功地推进到下一个元素,则为 true;如果枚举数越过集合的结尾,则为 false。
  19. //
  20. // 异常:
  21. // System.InvalidOperationException:
  22. // 在创建了枚举数后集合被修改了。
  23. bool MoveNext();
  24. //
  25. // 摘要:
  26. // 将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
  27. //
  28. // 异常:
  29. // System.InvalidOperationException:
  30. // 在创建了枚举数后集合被修改了。
  31. void Reset();
  32. }

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来遍历,而数组数据可以使用下标操作。

C#中的 IList, ICollection ,IEnumerable 和 IEnumerator的更多相关文章

  1. IList, ICollection ,IEnumerable AND IEnumerator in C#

    IList, ICollection ,IEnumerable 很显然,这些都是集合接口的定义,先看看定义: // 摘要: // 表示可按照索引单独访问的对象的非泛型集合. [ComVisible(t ...

  2. IEnumerable、IEnumerator、ICollection、IList、List的继承关系及简单使用

    IEnumerable和IEnumerable<T>接口在.NET中是非常重要的接口,它允许开发人员定义foreach语句功能的实现并支持非泛型方法的简单的迭代,IEnumerable和I ...

  3. C#编程之IList<T>、List<T>、ArrayList、IList, ICollection、IEnumerable、IEnumerator、IQueryable 和 IEnumerable的区别

    额...今天看了半天Ilist<T>和List<T>的区别,然后惊奇的发现使用IList<T>还是List<T>对我的项目来说没有区别...  在C#中 ...

  4. 细说 C# 中的 IEnumerable和IEnumerator接口

    我们先思考几个问题: 为什么在foreach中不能修改item的值? 要实现foreach需要满足什么条件? 为什么Linq to Object中要返回IEnumerable? 接下来,先开始我们的正 ...

  5. IEnumerable和IEnumerator

    概述 IEnumerable和IEnumerator接口存在的意义:用来实现迭代的功能! public interface IEnumerable { IEnumerator GetEnumerato ...

  6. 【5min+】你怎么穿着品如的衣服?IEnumerable AND IEnumerator

    系列介绍 简介 [五分钟的dotnet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的. ...

  7. 15.IEnumerable和IEnumerator

    先说IEnumerable,我们每天用的foreach你真的懂它吗? 阅读目录 自己实现迭代器 yield的使用 怎样高性能的随机取IEnumerable中的值 我们先思考几个问题: 为什么在fore ...

  8. IEnumerable和IEnumerator接口

    我们先思考几个问题:1.为什么在foreach中不能修改item的值?(IEnumerator的Current为只读)2.要实现foreach需要满足什么条件?(实现IEnumerator接口来实现的 ...

  9. [转]那些年我还不懂:IList,ICollection,IEnumerable,IEnumerator,IQueryable

    1.首先看一个简单的例子 int[] myArray = { 1, 32, 43, 343 }; IEnumerator myie = myArray.GetEnumerator(); myie.Re ...

随机推荐

  1. Objective - C 中NSString (字符串)与C中的字符串转换问题

    NSString是一个常用的类,NSString是原生支持unicode C中的字符串 比如char * a = "hello world";  是utf8类型的, char* d ...

  2. 你好,C++(3)2.1 一个C++程序的自白

    第2部分 与C++第一次亲密接触 在浏览了C++“三分天下”的世界版图之后,便对C++有了基本的了解,算是一只脚跨入了C++世界的大门.那么,怎样将我们的另外一只脚也跨入C++世界的大门呢?是该即刻开 ...

  3. 使用gSoap规避和修改ONVIF标准类型结构的解析

    ONVIF/gSoap依赖关系及问题 ONVIF是一组服务规范,标准参考 gSoap是一套基于实现SOAP通信接口的工具链 即是,当我们需要访问ONVIF的Web Service或实现对ONVIF部分 ...

  4. hold

    嘿嘿,很久没写博客了.一懒一拖一浮躁就不行了. 果然烦心事太多,一直懒得编程.结果还是编程才能平复我啊! 明天那什么,别担心,平常心嘛! 还好,看了几部电影,不算没收获.自己有意思就看看电影,别瞎想啥 ...

  5. underscorejs-toArray学习

    2.23 toArray 2.23.1 语法: _.toArray(list) 2.23.2 说明: 把list(任何可以迭代的对象)转换成一个数组,在转换arguments对象时非常有用. 2.23 ...

  6. 在2015中使用V12版本的ReportView控件,会导致winform窗体不能正常打开

    在2015中使用V12版本的ReportView控件,会导致winform窗体不能正常打开,使用V10版本没问题,但2015中默认使用的就是V12版本,所以需要避免使用V12版本

  7. PHP获取每月第一天与最后一天

    <?phpfunction getthemonth($date){$firstday = date('Y-m-01', strtotime($date));$lastday = date('Y- ...

  8. YII 验证邮箱和QQ号码

    //验证邮箱非空,和邮箱格式                    //验证邮箱非空,和邮箱格式                     array("email","e ...

  9. Python【第七篇】面向对象进阶

    大纲 一.面向对象高级语法 1.静态方法.类方法.属性方法 2.类的特殊成员方法 3.反射 二.异常处理 三.网络编程之socket基础 一.面向对象高级语法 1.静态方法:名义上归类管理,实际上静态 ...

  10. 新站如何做SEO及注意事项

    最近公司做了新网站,完成后运营优化的工作就落在我身上了,由于之前也没有.就去网上百度了一下,上了各种论坛查阅大牛的博客.自己也总结了一些要点,在这里和大家分享一下.新网站大家可以点击查看牛羊养殖在线. ...