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);
}
こんなことも自在に行える。