IList, ICollection ,IEnumerable AND IEnumerator in C#
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);
}
// 摘要:
// 定义所有非泛型集合的大小、枚举数和同步方法。
[ComVisible(true)]
public interface ICollection : IEnumerable
{
int Count { get; } bool IsSynchronized { get; } object SyncRoot { get; } void CopyTo(Array array, int index);
}
// 摘要:
// 公开枚举数,该枚举数支持在非泛型集合上进行简单迭代。
[ComVisible(true)]
[Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerable
{
// 摘要:
// 返回一个循环访问集合的枚举数。
//
// 返回结果:
// 一个可用于循环访问集合的 System.Collections.IEnumerator 对象。
[DispId(-)]
IEnumerator GetEnumerator();
}
可以看出,所有集合接口的祖宗是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来遍历,而数组数据可以使用下标操作。
IList, ICollection ,IEnumerable AND IEnumerator in C#的更多相关文章
- C#中的 IList, ICollection ,IEnumerable 和 IEnumerator
IList, ICollection ,IEnumerable 很显然,这些都是集合接口的定义,先看看定义: // 摘要: // 表示可按照索引单独访问的对象的非泛型集合. [ComVisible(t ...
- IEnumerable、IEnumerator、ICollection、IList、List的继承关系及简单使用
IEnumerable和IEnumerable<T>接口在.NET中是非常重要的接口,它允许开发人员定义foreach语句功能的实现并支持非泛型方法的简单的迭代,IEnumerable和I ...
- C#编程之IList<T>、List<T>、ArrayList、IList, ICollection、IEnumerable、IEnumerator、IQueryable 和 IEnumerable的区别
额...今天看了半天Ilist<T>和List<T>的区别,然后惊奇的发现使用IList<T>还是List<T>对我的项目来说没有区别... 在C#中 ...
- IEnumerable和IEnumerator
概述 IEnumerable和IEnumerator接口存在的意义:用来实现迭代的功能! public interface IEnumerable { IEnumerator GetEnumerato ...
- 【5min+】你怎么穿着品如的衣服?IEnumerable AND IEnumerator
系列介绍 简介 [五分钟的dotnet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的. ...
- [转]那些年我还不懂:IList,ICollection,IEnumerable,IEnumerator,IQueryable
1.首先看一个简单的例子 int[] myArray = { 1, 32, 43, 343 }; IEnumerator myie = myArray.GetEnumerator(); myie.Re ...
- IList,ICollection,IEnumerable,IEnumerator,IQueryable
http://www.cnblogs.com/edison1105/archive/2012/07/30/2616082.html 1.首先看一个简单的例子 int[] myArray = { 1, ...
- ICollection IEnumerable/IEnumerator IDictionaryEnumerator yield
Enumerable和IEnumerator接口是.NET中非常重要的接口,二者区别: 1. IEnumerable是个声明式的接口,声明实现该接口的类就是“可迭代的enumerable”,但并没用说 ...
- IEnumerable和IEnumerator 详解 (转)
原文链接:http://blog.csdn.net/byondocean/article/details/6871881 参考链接:http://www.cnblogs.com/hsapphire/a ...
随机推荐
- c++ 回调类成员函数实现
实现类成员函数的回调,并非静态函数:区分之 #ifndef __CALLBACK_PROXY_H_ #define __CALLBACK_PROXY_H_ template <typename ...
- SQL Server索引进阶:第十三级,插入,更新,删除
在第十级到十二级中,我们看了索引的内部结构,以及改变结构造成的影响.在本文中,继续查看Insert,update,delete和merge造成的影响.首先,我们单独看一下这四个命令. 插入INSERT ...
- css3 选择器的比较(一) -- 以字符串开头
一. 以“字符串”开头 两种用法的区别是: a. 以字符串开头,需要用"-"分割开, b. 以字符串开头,不需要任何分隔符 1. 资料 a) b) 2. html代码 < ...
- BZOJ 2302: [HAOI2011]Problem c( dp )
dp(i, j)表示从i~N中为j个人选定的方案数, 状态转移就考虑选多少人为i编号, 然后从i+1的方案数算过来就可以了. 时间复杂度O(TN^2) ------------------------ ...
- 简单的scrapy实战:爬取腾讯招聘北京地区的相关招聘信息
简单的scrapy实战:爬取腾讯招聘北京地区的相关招聘信息 简单的scrapy实战:爬取腾讯招聘北京地区的相关招聘信息 系统环境:Fedora22(昨天已安装scrapy环境) 爬取的开始URL:ht ...
- 逻辑(if)、关系、数字、条件运算符
if语句 if-else if-else if(a==0){1} else if (a>0){2} else{3} 特点:1.2.3只有一个括号会被执行 陷阱 1.if(a!=0) ...
- CoreText 简单 使用
- (void)drawRect:(CGRect)rect { NSString *longText = @"CoreText"; /* ... */ NSRange rang = ...
- 从头编译ARM交叉编译环境
首先Cygwin需安装基本的命令 例如make binutils gcc 还有diffutils 没有他会报找不到cmp命令 这些都可以在setup.exe中找到 编译gcc时,需要注意一个原则:不要 ...
- pyhton
http://panda.www.net.cn/cgi-bin/check.cgi?area_domain= http://whois.chinaz.com/ beautifulsoup4 impor ...
- 面试题之 query转为obj
要注意处理编码后的字串 对于a=123要得到number形的值 function parseQueryString(url) { var obj = {}; var query = url.sear ...