IEnumerable接口

      在LINQ中,数据源和查询结果实际上都是IEnumerable<T>或IQueryable<T>类型对象,所以可以通过使用普通对象的形式(调用方法、使用属性等)对数据源进行查询或使用查询结果数据。

 

IEnumerable<T>接口

IEnumerable<T>泛型接口支持在制定数据集合上进行迭代操作。它定义了一组扩展方法,用来对数据集合中的元素进行遍历、过滤、排序、搜索等操作。在LINQ中,数据源实际上是实现了接口IEnumerable<T>的类,通过select子句返回的查询结果页是一个实现了IEnumerable<T>的类。

在.NET类库中,IEnumerable<T>接口提供了大量与查询相关的方法。这些方法实际上是以扩展方法的形式定义,但是由于它的作用类型也为IEnumerable<T>接口,所以使用上和成员方法很类似。

IEnumerable<T>接口主要成员

 成员

 功能

 Aggregate  对序列应用累加器函数,可以指定累加方法
 Sum

 计算序列中所有元素的和,返回值有int、long、float、double、decimal类型,并且可以指定元素到数值的映射方法

 Average

 计算序列中所有元素的平均值,返回值有int、long、float、double、decimal类型,并且可以指定元素到数值的映射方法

 Max  计算序列中所有元素的最大值,返回值有int、long、float、double、decimal类型,并且可以指定元素到数值的映射方法
 Min  计算序列中所有元素的最小值,返回值有int、long、float、double、decimal类型,并且可以指定元素到数值的映射方法
 All  检查是否序列中所有元素都满足条件,可以指定条件判断方法。如果所有元素都满足条件返回True,否则返回False
 Any  检查序列中是否有任何一个元素满足条件,可以指定条件的判断方法。如果有一个以上(含一个)元素满足条件返回True,否则返回False
 Contains  检查数据系列中是否包含特定的元素,可以指定相等比较方法
 Count  返回序列中满足指定条件的元素的数量,可以指定条件判断方法
 LongCount  返回序列中满足指定条件的元素的长数量,可以指定条件判断方法
 Cast  将IEnumerable中的元素转换为指定的数据类型
 DefaultIfEmpty  返回序列中指定位置的元素。如果序列为空,则返回默认的元素值
 ElementAt  返回序列中指定索引处的元素
 ElementAtOrDefault  返回序列中指定索引处的元素。如果序列为空,则返回默认值
 First  返回序列中满足指定条件的第一个元素,可以指定条件判断方法
 FirstOrDefault  返回序列中满足指定条件的第一个元素。如果不存在则返回默认值,也可以指定条件判断方法
 Last  返回序列中满足指定条件的最后一个元素,可以指定条件判断方法
 LastOrDefault  返回序列中满足指定条件的最后一个元素。如果不存在则返回默认值,也可以指定条件判断方法
 Single  返回序列中满足指定条件的唯一元素。如果不止一个元素满足条件会引发一场,可以指定条件判断方法
 SingleOrDefault 返回序列中满足指定条件的唯一元素。如果不存在则返回默认值,如果不止一个元素满足条件会引发一场,可以指定条件判断方法 
Reverse 反转序列中元素的顺序 
 Distinct 返回序列中不重复的元素的集合,可以指定相等比较方法 
 Concat 连接两个序列,直接首尾相连。返回结果可能存在重复数据 
 Except 获取两个元素集合的差集,可以指定相等比较方法 
 Intersect  获取两个元素集合的交集,可以指定相等比较方法
 Union  获取两个元素集合的并集,可以指定相等比较方法

 SequenceEqual

比较两个序列是否相等,可以指定相等比较方法 
 Where 根据制定条件对集合中元素进行筛选,返回满足条件的元素集合 
 Skip 跳过序列中指定数量的元素,然后返回剩余的元素 
 SkipWhile 跳过序列中满足指定条件的元素,然后返回剩余的元素,可以指定条件判断方法 
 Take 从序列的开头返回指定数量的连续元素 
 TakeWhile 返回从序列开始的满足指定条件的连续元素,可以指定条件判断方法 
 ToArray 从IEnumerable<T>创建一个数组 
 ToList 从IEnumerable<T>创建一个List<T> 

从上表可以看出,IEnumerable<T>提供的方法包括数值运算(Sum、Min、Max、Average)、元素数量(Count、LongCount)、取值(First、Last、ElementAt等)、提取子集(Skip、SkipWhile、Take、TakeWhile、)集合操作(Reverse、Concat、Distinct、Except、Intersect、Union、SequenceEqual等)。这些方法提供了LINQ所需要的所有操作。

注意:

IEnuerable<T>继承自IEnumerable<T>接口,所以它也包含IEnumerable接口的所有方法,所以还包括Select()、SelectMany()、Repeat()等方法。

另外,IQuery<T>接口从IEnumerable<T>派生而来,通常也可以作为数据源使用,它的使用和IEnumerable<T>类似。

 

展开阅读全文

【求助】IEnumerable接口的实现

02-25

MSDN中对于IEnumerable接口的实现给出了如下示例代码:rn[code=csharp]using System;rnusing System.Collections;rnrnpublic class Personrnrn public Person(string fName, string lName)rn rn this.firstName = fName;rn this.lastName = lName;rn rnrn public string firstName;rn public string lastName;rnrnrnpublic class People : IEnumerablernrn private Person[] _people;rn public People(Person[] pArray)rn rn _people = new Person[pArray.Length];rnrn for (int i = 0; i < pArray.Length; i++)rn rn _people[i] = pArray[i];rn rn rnrn IEnumerator IEnumerable.GetEnumerator()rn rn return (IEnumerator) GetEnumerator();rn rnrn public PeopleEnum GetEnumerator()rn rn return new PeopleEnum(_people);rn rnrnrnpublic class PeopleEnum : IEnumeratorrnrn public Person[] _people;rnrn // Enumerators are positioned before the first elementrn // until the first MoveNext() call.rn int position = -1;rnrn public PeopleEnum(Person[] list)rn rn _people = list;rn rnrn public bool MoveNext()rn rn position++;rn return (position < _people.Length);rn rnrn public void Reset()rn rn position = -1;rn rnrn object IEnumerator.Currentrn rn getrn rn return Current;rn rn rnrn public Person Currentrn rn getrn rn tryrn rn return _people[position];rn rn catch (IndexOutOfRangeException)rn rn throw new InvalidOperationException();rn rn rn rnrnrnclass Apprnrn static void Main()rn rn Person[] peopleArray = new Person[3]rn rn new Person("John", "Smith"),rn new Person("Jim", "Johnson"),rn new Person("Sue", "Rabon"),rn ;rnrn People peopleList = new People(peopleArray);rn foreach (Person p in peopleList)rn Console.WriteLine(p.firstName + " " + p.lastName);rnrn rn[/code]rnrnIEnumerable接口中只有一个方法GetEnumerator,只要在class People当中实现GetEnumerator()就可以了,rnclass People当中已经有了一个rn[code=csharp]public PeopleEnum GetEnumerator()rn rn return new PeopleEnum(_people);rn [/code]rnrn那么rn[code=csharp]IEnumerator IEnumerable.GetEnumerator()rn rn return (IEnumerator) GetEnumerator();rn [/code]rn这个函数是什么意思?函数名是IEnumerable.GetEnumerator? 论坛

C#可枚举的接口IEnumerable

11-09

能使用foreach语句进行遍历的必须是实现了IEnuerable接口的类型,IEnumerable只有一个方法:IEnumerator GetEnumerator();rnrnIEnumerator有三个方法 object Current()//获取当前对象,bool MoveNext()//将游标移到下一个位置,void Reset()//将光标重置的第一个成员前面。rnrn以下是我写的一个例子。rnrnusing System;rnusing System.Collections.Generic;rnusing System.Linq;rnusing System.Text;rnusing System.Collections;rnrnnamespace ForeachAblernrn class Programrn rn static void Main(string[] args)rn rn CarStore _4s= new CarStore();rn foreach (Car item in _4s)rn rn Console.WriteLine(item.CarName); rn rn Console.ReadKey();rn rn rnrn public class Carrn rn private string _name;rn public string CarNamern rn getrn rn return this._name;rn rn setrn rn _name = value;rn rn rnrn public Car(string name)rn rn this._name = name;rn rn rn rn public class CarStore:IEnumerablern rn private Car[] _cars;rn public Car[] Carsrn rn getrn rn return _cars;rn rn setrn rn _cars = value;rn rn rnrn public CarStore()rn rn _cars = new Car[] new Car("吉利"),new Car("比亚迪"),new Car("力帆"),new Car("奔腾B70"),new Car("红旗");rn rnrn public IEnumerator GetEnumerator()rn rn return new CarEnumertor(this);rn rn rn public class CarEnumertor : IEnumeratorrn rn int _index;rn CarStore _newCarStore;rn public CarEnumertor(CarStore newCarStore)rn rn _index = -1;rn _newCarStore = newCarStore;rn rn public object Currentrn rn get return _newCarStore._cars[_index]; rn rnrn public bool MoveNext()rn rn if (_index < _newCarStore._cars.Length-1)rn rn _index++;rn return true;rn rn elsern rn return false;rn rn rnrn public void Reset()rn rn _index=-1;rn rn rnrn rnrn运行通过,显示出了5个car对象,但有一个疑惑的是关于 Reset方法,无论我将_index的值改为-1,0,1,甚至什么都不做,都没有影响最后结果,好像Reset方法没有执行一样。反而是构造函数的_index赋值结果会影响执行结果,将_index=0,第一个car对象就不会显示。不知为什么?rn 论坛

IEnumerable是否应该实现IEnumerable接口? 请高手讨论

07-05

C#2.0的遍历器(Iterator),应该是对Gamma提出的Iterator设计模式的实现。在C#中,如果某个类型继承了接口IEnumerable,或者继承了泛型接口IEnumerable,或者继承了泛型接口IEnumerable的任何一个构造类型(如IEnumerable),那么称该类型是“可遍历的”(“可枚举的”)。rnrnMSDN中创建遍历器的示例代码是:rnrnpublic class Stack: IEnumerablernrn T[] items;rn int count;rn public void Push(T data) ...rn public T Pop() ...rn public IEnumerator GetEnumerator()rn rn for (int i = count – 1; i >= 0; --i)rn yield return items[i];rn rnrnrn但这样编译将会报错“Stack不会实现接口成员IEnumerable.GetEnumerator”rnrn究其原因,是由于IEnumerable居然继承了IEnumerable接口,那么Stack也就隐含继承了IEnumerable,因此需要实现其返回类型为IEnumerator的GetEnumerator方法。在这里,类中需要加上下面的代码才能保证正确:rnrnIEnumerator IEnumerable.GetEnumerator()rnrn return GetEnumerator();rnrnrn这会给初学者带来很大的迷惑。有些外文资料解释说,所有的新的泛型接口都应该继承以前object型对应接口。个人认为,不应该让IEnumerable继承IEnumerable;在需要时,可以让一个类继承IEnumerable,又继承IEnumerable,那就把两个接口都写出来好了:rnpublic class Stack: IEnumerable, IEnumerablernrn但实际上,.NET Framwork中的大量泛型接口都不存在这种情况,如IComparer没有继承IComparer,ICollection没有继承ICollection,等等。rnrn而且,在.NET Framwork 2.0的Beta2版本中,并没有出现这种情况,而MSDN中的代码原来是可以通过编译的。只是到了正式版,IEnumerable就突然多继承了一个IEnumerable(此外还有IEnumerator继承了IEnumerator)rnrn 论坛

实现枚举接口的IEnumerator接口IEnumerable 的问题(请执教! 谢谢!

09-05

实现枚举接口的IEnumerator接口和IEnumerable 的问题rnusing System;rnusing System.Collections;rn class Programrn rn static void Main(string[] args)rn rn ImplementIE myImplementIE = new ImplementIE();rn foreach (int i in myImplementIE)rn rn Console.Write(i + "\t");rn rn IEnumerator myIEnumerator = myImplementIE.GetEnumerator();rn while (myIEnumerator.MoveNext())rn rn int i = (int)myIEnumerator.Current;rn Console.Write(i + "\t");rn rn Console.ReadLine();rn rn rnpublic class ImplementIE : IEnumerablernrn int[] myInt = new int[32];rn int currentindex = -1;rn public ImplementIE()rn rn for (int i = 0; i < 32; i++)rn rn myInt[i] = i * 10;rn rn rn public IEnumerator GetEnumerator()rn rn ClsIEnumerator myClsIEnumerator = new ClsIEnumerator(this);rn return myClsIEnumerator;rn rn class ClsIEnumerator : IEnumeratorrn rn ImplementIE myImplementIE;rn public ClsIEnumerator(ImplementIE myImplementIE)rn rn this.myImplementIE = myImplementIE;rn rn public object Currentrn rn getrn rn return myImplementIE.myInt[myImplementIE.currentindex];rn rn rn public void Reset()rn rn myImplementIE.currentindex = -1;rnrn rn public bool MoveNext()rn rn myImplementIE.currentindex++;rn if (myImplementIE.currentindex >= myImplementIE.myInt.Length)rn return false;rn elsern return true;rn rn rnrnrnrn问题如下:rn 1: rn public IEnumerator GetEnumerator()rn rn ClsIEnumerator myClsIEnumerator = new ClsIEnumerator(this);rn return myClsIEnumerator;rn rn接口IEnumerable定义方法GetEnumerator,此方法返回一个实现IEnumerator接口的类 rnpublic IEnumerator GetEnumerator() 在这个方法定义中 IEnumerator 是什么意思 返回值类型?但是它是接口名称rn2: ImplementIE myImplementIE;rn public ClsIEnumerator(ImplementIE myImplementIE)rn rn this.myImplementIE = myImplementIE;rn rn这是一个类的嵌套嘛?rn3:为什么在这个类中 class ClsIEnumerator : IEnumerator 操作的是public class ImplementIE : IEnumerable类对象rnIEnumerator接口通常由实现接口IEnumerable的类取得,接口IEnumerable定义方法GetEnumerator,此方法返回一个实现IEnumerator接口的类,rn实现IEnumerator接口的类通常以嵌套类的形式存在于实现接口IEnumerable的类内部。rn这句话如何理解?rn 论坛

没有更多推荐了,返回首页