IEnumerable天不遮我

IEnumerable及IEnumerable的泛型版本IEnumerable是一个接口,它只含有一个方法GetEnumerator。Enumerable这个静态类型含有很多扩展方法,其扩展的目标是IEnumerable

实现了这个接口的类可以使用Foreach关键字进行迭代(迭代的意思是对于一个集合,可以逐一取出元素并遍历之)。实现这个接口必须实现方法GetEnumerator。

实现一个继承IEnumerable的类型等同于实现方法GetEnumerator。想知道如何实现方法GetEnumerator,不妨思考下实现了GetEnumerator之后的类型在Foreach之下的行为:

假设我们有一个很简单的Person类(例子来自MSDN):

publicclassPerson{publicPerson(stringfName,stringlName){FirstName=fName;LastName=lName;}publicstringFirstName;publicstringLastName;}然后我们想构造一个没有实现IEnumerable的类型,其储存多个Person,然后再对这个类型实现IEnumerable。这个类型实际上的作用就相当于Person[]或List,但我们不能使用它们,因为它们已经实现了IEnumerable,故我们构造一个People类,模拟很多人(People是Person的复数形式)。这个类型允许我们传入一组Person的数组。所以它应当有一个Person[]类型的成员,和一个构造函数,其可以接受一个Person[],然后将Person[]类型的成员填充进去作为初始化。

//People类就是Person类的集合//但我们不能用List或者Person[],因为他们都实现了IEnumerable//我们要自己实现一个IEnumerable//所以请将People类想象成List或者类似物publicclassPeople:IEnumerable{privatereadonlyPerson[]_people;publicPeople(Person[]pArray){//构造一个Person的集合_people=newPerson[pArray.Length];for(vari=0;i

publicstaticvoidMain(string[]args){//新的Person数组Person[]peopleArray={newPerson("John","Smith"),newPerson("Jim","Johnson"),newPerson("Sue","Rabon"),};//People类实现了IEnumerablevarpeopleList=newPeople(peopleArray);//枚举时先访问MoveNext方法//如果返回真,则获得当前对象,返回假,就退出此次枚举foreach(PersonpinpeopleList)Console.WriteLine(p.FirstName+""+p.LastName);}复制代码但现在我们的程序不能运行,因为我们还没实现GetEnumerator方法。

GetEnumerator方法需要一个IEnumerator类型的返回值,这个类型是一个接口,所以我们不能这样写:

returnnewIEnumerator();因为我们不能实例化一个接口。我们必须再写一个类PeopleEnumerator,它继承这个接口,实现这个接口所有的成员:Current属性,两个方法MoveNext和Reset。于是我们的代码又变成了这样:

//实现IEnumerable需要实现GetEnumerator方法publicIEnumeratorGetEnumerator(){returnnewPeopleEnumerator();}在类型中:

publicclassPeopleEnumerator:IEnumerator{publicboolMoveNext(){thrownewNotImplementedException();}publicvoidReset(){thrownewNotImplementedException();}publicobjectCurrent{get;}}现在问题转移为实现两个方法,它们的功能看上去一目了然:一个负责将集合中Current向后移动一位,一个则将Current初始化为0。我们可以查看IEnumerator元数据,其解释十分清楚:

通过上面的文字,我们可以理解GetEnumerator方法,就是获得当前Enumerator指向的成员。我们引入一个整型变量position来记录当前的位置,并且先试着写下:

publicclassPeopleEnumerator:IEnumerator{publicPerson[]_peoples;publicobjectCurrent{get;}//当前位置publicintposition;//构造函数接受外部一个集合并初始化自己内部的属性_peoplespublicPeopleEnumerator(Person[]peoples){_peoples=peoples;}//如果没到集合的尾部就移动position,返回一个boolpublicboolMoveNext(){if(position<_peoples.Length){position++;returntrue;}returnfalse;}publicvoidReset(){position=0;}}

这看上去好像没问题,但一执行之后却发现:

通过不断的调试,最后完整的实现应当是:

publicclassPeopleEnumerator:IEnumerator{publicPerson[]People;//每次运行到MoveNext或Reset时,利用get方法自动更新当前位置指向的对象objectIEnumerator.Current{get{try{//当前位置的对象returnPeople[_position];}catch(IndexOutOfRangeException){thrownewInvalidOperationException();}}}//当前位置privateint_position=-1;publicPeopleEnumerator(Person[]people){People=people;}//当程序运行到foreach循环中的in时,就调用这个方法获得下一个person对象publicboolMoveNext(){_position++;//返回一个布尔值,如果为真,则说明枚举没有结束。//如果为假,说明已经到集合的结尾,就结束此次枚举return(_position_position=-1;}为什么当程序运行到in时,会呼叫方法MoveNext呢?我们并没有直接调用这个方法啊?当你试图查询IL时,就会得到答案。实际上下面两段代码的作用是相同的:

foreach(Titemincollection){...}IEnumeratorenumerator=collection.GetEnumerator();while(enumerator.MoveNext()){Titem=enumerator.Current;...}

THE END
1.C#IEnumerable.Where方法代码示例本文整理汇总了C#中IEnumerable.Where方法的典型用法代码示例。如果您正苦于以下问题:C# IEnumerable.Where方法的具体用法?C# IEnumerable.Where怎么用?C# IEnumerable.Where使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类IEnumerable的用法示例。 https://vimsky.com/examples/detail/csharp-ex---IEnumerable-Where-method.html
2.(转)IEnumerable和IEnumerator详解namespaceMyCarIEnumerator{publicclassGarage:IEnumerable{Car[]carArray=newCar[4];//启动时填充一些Car对象publicGarage(){carArray[0]=newCar("Rusty",30);carArray[1]=newCar("Clunker",50);carArray[2]=newCar("Zippy",30);carArray[3]=newCar("Fred",45);}publicIEnumeratorGetEnumerator(){return...https://www.jianshu.com/p/7943bbd826d7
3.如何批量遍历IEnumerable然后可以在方法中调用它。public IEnumerable<user> GetBatch(int pageNumber){    return ...https://m.imooc.com/wenda/detail/603656
1.IEnumerable介面(System.Collections)MicrosoftLearnCast<TResult>(IEnumerable) 將IEnumerable 的項目轉換成指定的型別。 OfType<TResult>(IEnumerable) 根據指定的型別篩選 IEnumerable 的專案。 AsParallel(IEnumerable) 啟用查詢的平行處理。 AsQueryable(IEnumerable) 將IEnumerable 轉換成 IQueryable。 適用於 產品版本 .NET Core 1.0, Core 1.1, Core 2.0, Core...https://msdn.microsoft.com/zh-tw/library/h1x9x1b1(v=vs.90)
2.C#IEnumerator,IEnumerable,Iteratorienumerable<int>C# IEnumerator,IEnumerable ,Iterator IEnumerator 枚举器接口 在C#语言中,大部分以“I”字母开头命名的都是接口,所以情理之中,IEnumerator也是一个接口。 对于面向对象语言来说,接口就是一份“协议”,它定义了一组方法、属性和事件的契约,任何类、结构体或枚举只要符合这个契约,就可以被认为实现了该接口,可以被贴...https://blog.csdn.net/jshxjd/article/details/143665403
3.C#中IEnumerableICollectionIListList之间的区别C#教程按照功能排序:List<T> 《IList<T> 《ICollection<T>《IEnumerable<T> 按照性能排序:IEnumerable<T>《ICollection<T>《IList<T>《List<T> 另一种解释: ICollection 接口是 System.Collections 命名空间中类的基接口,ICollection 接口扩展 IEnumerable,IDictionary 和 IList 则是扩展 ICollection 的更为专用的接口。如果...https://www.jb51.net/article/218178.htm
4.C#中IEumerable的简单了解51CTO博客一、IEnumerable简单介绍 IEnumerable是可枚举类型,一般在迭代时应用广泛,如foreach中要循环访问的集合或数组都实现了IEnumerable接口。只要能够遍历,都直接或间接实现了IEnumerable接口。如:String类型的对象,可遍历,输出时以字符输出,间接实现了IEnumerable接口,"OOP"遍历打印就是'O','O','P';又如int类型没有实现IEnum...https://blog.51cto.com/u_4018548/6420389
5.StephenWaltheronASP.NETMVC6:IEnumerable GetCustomers(); 7: 8:} The IData interface has one method named GetCustomers() that, when implemented, should return a list of customers. Here’s a quick sample of how you can mock this interface with Typemock Isolator: ...https://weblogs.asp.net/stephenwalther/archive/2008/03/16/tdd-introduction-to-typemock-isolator.aspx
6....acommaseparatedlistfromIList<string>orIEnumerable<...What is the cleanest way to create a comma-separated list of string values from anIList<string>orIEnumerable<string>? String.Join(...)operates on astring[]so can be cumbersome to work with when types such asIList<string>orIEnumerable<string>cannot easily be converted into a string ...https://stackoverflow.com/questions/799446/creating-a-comma-separated-list-from-iliststring-or-ienumerablestring
7.DDD理论学习系列(12)仓储腾讯云开发者社区对于这种问题,我们最好在仓储中的方法中,比如List()或者ListActive()做默认处理,而不是在应用服务层每次去指定查询条件。 但具体是返回 IQueryable还是IEnumerable每个人的看法不一,具体可参考Repository 返回 IQueryable?还是 IEnumerable?。 5. 事务管理和工作单元...https://cloud.tencent.com/developer/article/1018485