以下のようなプログラムを書いています。
- 指定されたディレクトリで正しい拡張子を持つすべてのファイルを検索します
- Foreach、それらのファイルで特定の文字列のすべての出現箇所を検索します
- 各行を印刷する
これを一連のジェネレーター関数 (yield return
一度に 1 つの項目を呼び出して遅延ロードされたもののみを返すもの) として機能的に記述したいので、私のコードは次のようになります。
IEnumerable<string> allFiles = GetAllFiles();
IEnumerable<string> matchingFiles = GetMatches( "*.txt", allFiles );
IEnumerable<string> contents = GetFileContents( matchingFiles );
IEnumerable<string> matchingLines = GetMatchingLines( contents );
foreach( var lineText in matchingLines )
Console.WriteLine( "Found: " + lineText );
これで問題ありませんが、最後にいくつかの統計を出力したいと思います。このようなもの:
Found 233 matches in 150 matching files. Scanned 3,297 total files in 5.72s
問題は、上記のように「純粋な関数」スタイルでコードを記述すると、各項目が遅延ロードされることです。
最後の foreach ループが完了するまで、合計で一致するファイルの数しかわかりません。また、一度に 1 つのアイテムしかyield
編集されないため、コードには以前に見つかったものの数を追跡する場所がありません。LINQ のmatchingLines.Count()
メソッドを呼び出すと、コレクションが再列挙されます。
この問題を解決する方法はたくさん考えられますが、どれもやや醜いようです。これは、人々が以前にやったことがあると思います。これを行うためのベスト プラクティスの方法を示す優れたデザイン パターンがあると確信しています。
何か案は?乾杯