Advent LINQ (2): TextReader.AsEnumerable

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);
}

こんなことも自在に行える。

投稿者:

kekyo

A strawberry red slime mold. Likes metaprogramming. MA. Bicycle rider. http://amzn.to/1SeuUwD