要了解yield
,你需要了解什麼時候使用IEnumerator
和IEnumerable
(因爲你必須使用其中任何一個) 。以下示例可幫助您瞭解差異。
首先,看看下面的類,它實現了兩個方法 - 一個返回IEnumerator<int>
,一個返回IEnumerable<int>
。 ,
// 2 iterators, one as IEnumerator, one as IEnumerable
public class Iterator
{
public static IEnumerator<int> IterateOne(Func<int, bool> condition)
{
for(var i=1; condition(i); i++) { yield return i; }
}
public static IEnumerable<int> IterateAll(Func<int, bool> condition)
{
for(var i=1; condition(i); i++) { yield return i; }
}
}
現在,如果你使用IterateOne
你可以做到以下幾點::我會告訴你,有在使用中有很大的區別,雖然2種方法的代碼是尋找類似
// 1. Using IEnumerator allows to get item by item
var i=Iterator.IterateOne(x => true); // iterate endless
// 1.a) get item by item
i.MoveNext(); Console.WriteLine(i.Current);
i.MoveNext(); Console.WriteLine(i.Current);
// 1.b) loop until 100
int j; while (i.MoveNext() && (j=i.Current)<=100) { Console.WriteLine(j); }
1.A)打印:
1
2
1。B)打印:
3
4
...
100
,因爲它繼續語句都被執行後1.A右)計數。
您可以看到,您可以使用MoveNext()
逐項推進。
相比之下,IterateAll
允許您使用foreach
也LINQ報表更大的安慰:
// 2. Using IEnumerable makes looping and LINQ easier
var k=Iterator.IterateAll(x => x<100); // limit iterator to 100
// 2.a) Use a foreach loop
foreach(var x in k){ Console.WriteLine(x); } // loop
// 2.b) LINQ: take 101..200 of endless iteration
var lst=Iterator.IterateAll(x=>true).Skip(100).Take(100).ToList(); // LINQ: take items
foreach(var x in lst){ Console.WriteLine(x); } // output list
2.A)打印:
1
2
。 ..
99
2.B)打印:
101
102
...
200
注:由於IEnumerator<T>
和IEnumerable<T>
是仿製藥,他們可以與任何類型一起使用。但是,爲了簡單起見,在我的示例中使用了int
,其類型爲T
。
這意味着,您可以使用返回類型IEnumerator<ProductMixHeader>
或IEnumerable<ProductMixHeader>
(您在問題中提到的自定義類)之一。
List<ProductMixHeader>
類型沒有實現任何這些接口,這就是爲什麼你不能這樣使用它的原因。但是例2.b)顯示瞭如何從中創建一個列表。
我喜歡積極的方法'追求少吸';-)。 – 2008-11-25 14:21:04
這個幾乎相同的問題有一個很好的雷蒙德陳的東西的鏈接:http://stackoverflow.com/questions/39476/what-is-the-yield-keyword-used-for-in-c – 2008-11-25 14:24:32