在面向對象的開發過程中,常常需要創建若干對象,並進行對象的操作和查詢,在創建對象前,首先需要聲明一個類爲對象提供描述,示例代碼如下所示。
using System;
using System.Collections.Generic;
using System.Linq; //使用LINQ命名控件
using System.Text;
namespace IEnumeratorSample
{
class Person //定義一個Person類
{
public string Name; //定義Person的名字
public string Age; //定義Person的年齡
public Person(string name, string age) //爲Person初始化(構造函數)
{
Name = name; //配置Name值
Age = age; //配置Age值
}
}
上述代碼定義了一個Person類並抽象一個Person類的屬性,這些屬性包括Name和Age。Name和Age屬性分別用於描述Person的名字和年齡,用於數據初始化。初始化之後的數據就需要創建一系列Person對象,通過這些對象的相應屬性能夠進行對象的訪問和遍歷,示例代碼如下所示。
class Program
{
static void Main(string[] args)
{
Person[] per = new Person[2] //創建並初始化2個Person對象
{
new Person("guojing","21"), //通過構造函數構造對象
new Person("muqing","21"), //通過構造函數構造對象
};
foreach (Person p in per) //遍歷對象
Console.WriteLine("Name is " + p.Name + " and Age is " + p.Age);
Console.ReadKey();
}
}
}
上述代碼創建並初始化了2個Person對象,並通過foreach語法進行對象的遍歷。但是上述代碼是在數組中進行查詢的,就是說如果要創建多個對象,則必須創建一個對象的數組,如上述代碼中的Per變量,而如果需要直接對對象的集合進行查詢,卻不能夠實現查詢功能。例如增加一個構造函數,該構造函數用戶構造一組Person對象,示例代碼如下所示。
private Person[] per;
public Person(Person[] array) //重載構造函數,迭代對象
{
per = new Person[array.Length]; //創建對象
for (int i = 0; i < array.Length; i++) //遍歷初始化對象
{
per[i] = array[i]; //數組賦值
}
}
上述構造函數動態的構造了一組People類的對象,那麼應該也能夠使用foreach語句進行遍歷,示例代碼如下所示。
Person personlist = new Person(per); //創建對象
foreach (Person p in personlist) //遍歷對象
{
Console.WriteLine("Name is " + p.Name + " and Age is " + p.Age);
}
在上述代碼的foreach語句中,直接在Person類的集合中進行查詢,系統則會報錯“ConsoleApplication1.Person”不包含“GetEnumerator”的公共定義,因此foreach語句不能作用於“ConsoleApplication1.Person”類型的變量,因爲Person類並不支持foreach語句進行遍歷。爲了讓相應的類能夠支持foreach語句執行遍歷操作,則需要實現派生自類IEnumerable並實現IEnumerable接口,示例代碼如下所示。
public IEnumerator GetEnumerator() //實現接口
{
return new GetEnum(_people);
}
爲了讓自定義類型能夠支持foreach語句,則必須對Person類的構造函數進行編寫並實現接口,示例代碼如下所示。
class Person:IEnumerable //派生自IEnumerable,同樣定義一個Personl類
{
public string Name; //創建字段
public string Age; //創建字段
public Person(string name, string age) //字段初始化
{
Name = name; //配置Name值
Age = age; //配置Age值
}
public IEnumerator GetEnumerator() //實現接口
{
return new PersonEnum(per); //返回方法
}
}
上述代碼重構了Person類並實現了接口,接口實現的具體方法如下所示。
class PersonEnum : IEnumerator //實現foreach語句內部,並派生
{
public Person[] _per; //實現數組
int position = -1; //設置“指針”
public PersonEnum(Person[] list)
{
_per = list; //實現list
}
public bool MoveNext() //實現向前移動
{
position++; //位置增加
return (position < _per.Length); //返回布爾值
}
public void Reset() //位置重置
{
position = -1; //重置指針爲-1
public object Current //實現接口方法
{
get
{
try
{
return _per[position]; //返回對象
}
catch (IndexOutOfRangeException) //捕獲異常
{
throw new InvalidOperationException(); //拋出異常信息
}
}
}
}
上述代碼實現了foreach語句的功能,當開發Person類初始化後就可以直接使用Personal類對象的集合進行LINQ查詢,示例代碼如下所示。
static void Main(string[] args)
{
Person[] per = new Person[2] //同樣初始化並定義2個Person對象
{
new Person("guojing","21"), //構造創建新的對象
new Person("muqing","21"), //構造創建新的對象
};
Person personlist = new Person(per); //初始化對象集合
foreach (Person p in personlist) //使用foreach語句
Console.WriteLine("Name is " + p.Name + " and Age is " + p.Age);
Console.ReadKey();
}
從上述代碼中可以看出,初始化Person對象時初始化的是一個對象的集合,在該對象的集合中可以通過LINQ直接進行對象的操作,這樣做即封裝了Person對象也能夠讓編碼更加易讀。在.NET Framework 3.5中,LINQ支持數組的查詢,開發人員不必自己手動創建IEnumerable和IEnumerable<T>接口以支持某個類型的foreach編程方法,但是IEnumerable和IEnumerable<T>是LINQ中非常重要的接口,在LINQ中也大量的使用IEnumerable和IEnumerable<T>進行封裝,示例代碼如下所示。
public static IEnumerable<TSource> Where<TSource>
(this IEnumerable<TSource> source,Func<TSource, Boolean> predicate) //內部實現
{
foreach (TSource element in source) //內部遍歷傳遞的集合
{
if (predicate(element))
yield return element; //返回集合信息
}
}
上述代碼爲LINQ內部的封裝,從代碼中可以看到,在LINQ內部也大量的使用了IEnumerable和IEnumerable<T>接口實現LINQ查詢。IEnumerable原本就是.NET Framework中最基本的集合訪問器,而LINQ是面向關係(有序N元組集合)的,自然也就是面向IEnumerable<T>的,所以瞭解IEnumerable和IEnumerable<T>對LINQ的理解是有一定幫助的。