コードを考えてみましょう:
class Program
{
static void Main(string[] args)
{
var test = new EnumTest();
test.ConsumeEnumerable2Times();
Console.ReadKey();
}
}
public class EnumTest
{
public IEnumerable<int> CountTo10()
{
for (var i = 0; i <= 10; i++)
yield return i;
}
public void ConsumeEnumerable2Times()
{
var enumerable = CountTo10();
foreach (var n in enumerable)
{
foreach (int i in enumerable)
{
Console.WriteLine("Outer: {0}, Inner: {1}", n, i);
}
}
}
}
このコードは出力を生成します:
Outer: 0, Inner: 1
Outer: 0, Inner: 2
...
Outer: 1, Inner: 0
Outer: 1, Inner: 1
...
Outer: 10, Inner: 10
IEnumerableを使用すると、同じコレクションを何度も列挙できます。IEnumerableは、実際には、列挙の要求ごとにIEnumeratorの新しいインスタンスを返します。
上記の例では、メソッドEnumTest()が1回呼び出されましたが、返されたIEnumerableが2回使用されました。毎回独立して10まで数えました。
これが、「複数の消費者が互いに干渉することなく、コレクションを一度に列挙できる」理由です。同じIEnumerableオブジェクトを2つのメソッドに渡すことができ、それらはコレクションを個別に列挙します。IEnumeratorを使用すると、それを実現することはできません。
私の英語について申し訳ありません。