此外,您還可以在完全一般的集合中使用 C# 迭代程序 ,如圖 4 所示。當使用一般集合和迭代程序時,編譯器從聲明集合(本例中的 string)所用的類中型知道 foreach 循環內 IEnumerable <ItemType> 所 用的特定類型:
Figure 4Providing Iterators on a Generic Linked List
//K is the key, T is the data item
class Node<K,T>
{
public K Key;
public T Item;
public Node<K,T> NextNode;
}
public class LinkedList<K,T> : IEnumerable<T>
{
Node<K,T> m_Head;
public IEnumerator<T> GetEnumerator()
{
Node<K,T> current = m_Head;
while(current != null)
{
yIEld return current.Item;
current = current.NextNode;
}
}
/* More methods and members */
}
圖 4
LinkedList<int,string> list = new LinkedList<int,string>();
/* Some initialization of list, then */
foreach(string item in list)
{
Trace.WriteLine(item);
}
這與任何其他從一般接口進行的派生 相似。如果出於某些原因想中途停止迭代,請使用 yIEld break 語句。例如,下 面的迭代程序將僅僅產生數值 1、2 和 3:
public IEnumerator<int> GetEnumerator()
{
for(int i = 1;i< 5;i++)
{
yIEld return i;
if(i > 2)
yIEld break;
}
}
您的集合可 以很容易地公開多個迭代程序,每個迭代程序都用於以不同的方式遍歷集合。例 如,要以倒序遍歷 CityCollection 類,提供了名為 Reverse 的 IEnumerable <string> 類型的屬性:
public class CityCollection
{
string[] m_CitIEs = {"New York","Paris","London"};
public IEnumerable<string> Reverse
{
get
{
for(int i=m_CitIEs.Length-1; i>= 0; i--)
yield return m_CitIEs[i];
}
}
}
這樣就可以在 foreach 循環中使用 Reverse 屬性:
CityCollection collection = new CityCollection();
foreach(string city in collection.Reverse)
{
Trace.WriteLine(city);
}
對於在何處以及如何使用 yield return 語句是有一些限制的。包含 yield return 語句的方法或屬性不能再包含 其他 return 語句,因為這樣會錯誤地中斷迭代。不能在匿名方法中使用 yield return 語句,也不能將 yIEld return 語句放到帶有 catch 塊的 try 語句中( 也不能放在 catch 塊或 finally 塊中)。