最終編集:
私はTimothyの回答を選択しましたが、C# のyieldステートメントを活用したよりキュートな実装が必要な場合は、Eamonの回答を確認してください: https://stackoverflow.com/a/19825659/145757
デフォルトでは、 LINQクエリは遅延ストリーミングされます。
ToArray
/完全なバッファリングToList
を提供しますが、最初は熱心で、次に無限シーケンスで完了するまでにかなりの時間がかかる場合があります。
両方の動作を組み合わせて使用する方法はありますか:次のクエリが既にクエリされた要素の生成をトリガーしないように、値が生成されるとその場でストリーミングとバッファリングを行います。
基本的な使用例は次のとおりです。
static IEnumerable<int> Numbers
{
get
{
int i = -1;
while (true)
{
Console.WriteLine("Generating {0}.", i + 1);
yield return ++i;
}
}
}
static void Main(string[] args)
{
IEnumerable<int> evenNumbers = Numbers.Where(i => i % 2 == 0);
foreach (int n in evenNumbers)
{
Console.WriteLine("Reading {0}.", n);
if (n == 10) break;
}
Console.WriteLine("==========");
foreach (int n in evenNumbers)
{
Console.WriteLine("Reading {0}.", n);
if (n == 10) break;
}
}
出力は次のとおりです。
Generating 0.
Reading 0.
Generating 1.
Generating 2.
Reading 2.
Generating 3.
Generating 4.
Reading 4.
Generating 5.
Generating 6.
Reading 6.
Generating 7.
Generating 8.
Reading 8.
Generating 9.
Generating 10.
Reading 10.
==========
Generating 0.
Reading 0.
Generating 1.
Generating 2.
Reading 2.
Generating 3.
Generating 4.
Reading 4.
Generating 5.
Generating 6.
Reading 6.
Generating 7.
Generating 8.
Reading 8.
Generating 9.
Generating 10.
Reading 10.
生成コードは 22 回トリガーされます。
列挙型が初めて反復されるときに、11回トリガーされるようにしたいと思います。
その後、2 番目の反復は、既に生成された値の恩恵を受けます。
次のようになります。
IEnumerable<int> evenNumbers = Numbers.Where(i => i % 2 == 0).Buffer();
Rxに精通している人にとっては、ReplaySubject
.