TextReaderで読み取れる行を、列挙子に変えてみる。
public static class LinqExtensions { public static IEnumerable<string> AsEnumerable(this TextReader tr) { try { while (true) { var line = tr.ReadLine(); if (line == null) { break; } yield return line; } } finally { tr.Dispose(); } } }
TextReaderは全て読み取った時点でDisposeを呼び出している。こうする事で、
foreach (var line in File.OpenText("VeryLongTextFile.txt").AsEnumerable()) { Console.WriteLine(line); }
という使い方をしても、列挙が終わればリーダーがクローズされるようになる。
一旦列挙子になってしまえば、
// フォルダ内のすべてのテキストファイルの、先頭・終端の空白を削除し、 // 空行や#で始まる行を除外して、ソートして表示 foreach (var line in from path in Directory.GetFiles(".", "*.txt", SearchOption.AllDirectories). AsParallel() from line in File.OpenText(path). AsEnumerable() let trim = line.Trim() where (trim.Length >= 1) && (trim.StartsWith("#") == false) orderby trim select trim) { Console.WriteLine(line); }
こんなことも自在に行える。