IEnumerable
(1) 成員: IEnumerator GetEnumerator()
1) 可以定義一個函數用於迭代, 即foreach...in...結構中
eg: public static IEnumerable Get()
{
for (int i = 0; i < 10; i++)
{
yield return i;
}
}
在Main()函數中就可以這樣使用:
foreach (int i in Get())
{
//TODO
}
2) 可以在類或結構中定義成員函數用於迭代對象或結構中的數據,可以定義多個
eg: class Test
{
public Test()
{}
public IEnumerable Get1()
{
for (int i = 0; i < 10; i++)
{
yield return i;
}
}
public IEnumerable Get2()
{
for (char ch = 'a'; ch <= 'z'; ch++)
{
yield return ch;
}
}
}
在Main()函數中就可以這樣使用:
Test test = new Test();
foreach (int i in test.Get1())
{
//TODO
}
foreach (char ch in test.Get2())
{
//TODO
}
3) 當類或結構繼承IEnumerable接口時該類就要實現IEnumerator GetEnumerator()方法, 還可以定義迭代屬性
eg: class Test : IEnumerable
{
public Test()
{}
public IEnumerator GetEnumerator()
{
for (int i = 0; i < 10; i++)
{
yield return i;
}
}
public IEnumerable BigToSmall
{
get
{
for (int i = 9; i >= 0; i--)
{
yield return i;
}
}
}
public IEnumerable SmallToBig
{
get
{
return this;
}
}
}
在Main()函數中可以這樣使用:
Test test = new Test();
foreach (int i in test) //這種迭代只有在Test繼承實現了IEnumerable接口後才能使用
{
//TODO
}
foreach (int i in test.BigToSmall)
{
//TODO
}
foreach (int i in test.SmallToBig)//這裡其實調用的還是Test類中實現的IEnumerable接口的IEnumerator GetEnumerator()方法, 因為SmallToBig返回的就是調用該屬性的對象本身
{
//TODO
}
IEnumerator: 枚舉數沒有對集合的獨占訪問權; 因此,枚舉通過集合在本質上不是一個線程安全的過程. 即使一個集合已進行同步, 其他線程仍可以修改該集合, 這將導致
枚舉數引發異常. 若要在枚舉過程中保證線程安全, 可以在整個枚舉過程中鎖定集合, 或者捕捉由於其他線程進行的更改而引發的異常.
1. 成員:
1) object Current //獲取當前的枚舉數, 最初Current停留在第一個枚舉數之前, 不能使用, 當調用一次MoveNext()後才指向第一個枚舉數
{
get { }
}
2) bool MoveNext(): 使Current指向下一個對象(如果存在的話), 存在下一個則返回true, 不存在則返回false
3) void Reset(): 重置Current, 使其恢復最初的狀態, 停留在第一個枚舉數之前
2. 使用yield return來模擬實現IEnumerator接口: 注意Current中存儲的都是object類型的對象, 要先進行類型轉換再處理
1) 可以定義一個返回IEnumerator類型的函數, 就實現了IEnumerator接口中的Current屬性,MoveNext()和Reset()方法
eg: public static Gets()
{
for (int i = 0; i < 10; i++)
{
yield return i;
}
}
在Main()函數中就可以這樣調用:
IEnumerator test = Gets();
while (test.MoveNext())
{
//TODO
}
2) 可以在類或對象中使用yield return 來返回一個IEnumerator類型的變量
eg: public Test
{
public Test()
{}
public IEnumerator BigToSmall
{
get
{
for (int i = 9; i >= 0; i--)
{
yield return i;
}
}
}
public IEnumerator SmallToBig()
{
for (int i = 0; i < 10; i++)
{
yield return i;
}
}
}
在Main()函數中就可以這樣使用:
Test test = new Test();
while (test.BigToSmall.MoveNext())
{
//TODO
}
while (test.SmallToBig().MoveNext())
{
//TODO
}