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

 // 摘要:
// 表示可按照索引单独访问的对象的非泛型集合。
[ComVisible(true)]
public interface IList : ICollection, IEnumerable
{ bool IsFixedSize { get; } bool IsReadOnly { get; } object this[int index] { get; set; } int Add(object value); void Clear(); bool Contains(object value); int IndexOf(object value); void Insert(int index, object value); void Remove(object value); void RemoveAt(int index);
}

IList

 // 摘要:
// 定义所有非泛型集合的大小、枚举数和同步方法。
[ComVisible(true)]
public interface ICollection : IEnumerable
{
int Count { get; } bool IsSynchronized { get; } object SyncRoot { get; } void CopyTo(Array array, int index);
}

ICollection

 // 摘要:
// 公开枚举数,该枚举数支持在非泛型集合上进行简单迭代。
[ComVisible(true)]
[Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerable
{
// 摘要:
// 返回一个循环访问集合的枚举数。
//
// 返回结果:
// 一个可用于循环访问集合的 System.Collections.IEnumerator 对象。
[DispId(-)]
IEnumerator GetEnumerator();
}

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

     // 摘要:
// 支持对非泛型集合的简单迭代。
[ComVisible(true)]
[Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerator
{
// 摘要:
// 获取集合中的当前元素。
//
// 返回结果:
// 集合中的当前元素。
object Current { get; } // 摘要:
// 将枚举数推进到集合的下一个元素。
//
// 返回结果:
// 如果枚举数成功地推进到下一个元素,则为 true;如果枚举数越过集合的结尾,则为 false。
//
// 异常:
// System.InvalidOperationException:
// 在创建了枚举数后集合被修改了。
bool MoveNext();
//
// 摘要:
// 将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
//
// 异常:
// System.InvalidOperationException:
// 在创建了枚举数后集合被修改了。
void Reset();
}

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. asp.net mvc生命周期学习

    ASP.NET MVC是一个扩展性非常强的框架,探究其生命周期对用Mock框架来模拟某些东西,达到单元测试效果,和开发扩展我们的程序是很好的. 生命周期1:创建routetable.把URL映射到ha ...

  2. 谈谈oracle中的临时表

    --------------------创建临时表 临时保存从xml字符串解析来的数据--------------------------- 会话级别临时表SQL> create global ...

  3. Tensor神经网络进行知识库推理

    本文是我关于论文<Reasoning With Neural Tensor Networks for Knowledge Base Completion>的学习笔记. 一.算法简介 网络的 ...

  4. jq 图片裁剪

    1.html <div class="jcropbox" style="display: none"> <img src="&quo ...

  5. 『重构--改善既有代码的设计』读书笔记----Move Method

    明确函数所在类的位置是很重要的.这样可以避免你的类与别的类有太多耦合.也会让你的类的内聚性变得更加牢固,让你的整个系统变得更加整洁.简单来说,如果在你的程序中,某个类的函数在使用的过程中,更多的是在和 ...

  6. Flask-SQLALchemy查询

    from: http://blog.sina.com.cn/s/blog_633277f90100kpvm.html 似乎ORM最难设计的部分是查询.特别是面向对象的查询,今天学习SQLAlchemy ...

  7. MSSQL中datetime与unix时间戳互转

    //ms sql datetime 转unix时间戳 SELECT DATEDIFF(s, '19700101',GETDATE()) //ms sql unix时间戳 转datetime 涉及到时区 ...

  8. winform布局格式

    一.默认布局 ★可以加panel,也可以不加: ★通过鼠标拖动控件的方式,根据自己的想法布局.拖动控件的过程中,会有对齐的线,方便操作: ★也可选中要布局的控件,在工具栏中有对齐工具可供选择,也有调整 ...

  9. iOS9 未受信任的企业级开发者

    升级iOS9,app打不开怎么办?6个步骤让你应对“未受信任的企业及开发者账号” 点开App,弹出未受信任的开发者,记住弹框中冒号后面的大写字母.关闭,进入设置. 进入通用 进入描述文件 找到所对应的 ...

  10. [151225] Python3 实现最大堆、堆排序,解决TopK问题

    参考资料: 1.算法导论,第6章,堆排序 堆排序学习笔记及堆排序算法的python实现 - 51CTO博客 堆排序 Heap Sort - cnblogs 小根堆实现优先队列:Python实现 -cn ...