while文をforeachに変換する


LINQ信者たるもの、あの処理もこの処理も全部LINQで書きたい!
のですが、たまに古いソースでwhile文でデータソースの
中身を列挙する処理などを見るとなんとなくイヤ〜な気持ちになります。

ありがちな物としてはCSVからオブジェクトを作る処理とか。
こんなの。

public static void Main()
{
   var fs = new FileStream("test.csv", FileMode.Open, FileAccess.Read);
   var sr = new StreamReader(fs, Encoding.GetEncoding("SHIFT_JIS"));

   while (!sr.EndOfStream)
   {
      string line = sr.ReadLine();
      var item = new Item(line);

      // 何か処理
   }

   sr.Close();
   fs.Close();
}

このwhile文を滅ぼしたくて、以下のようなクラスを作って見ました。

IterUtil.cs
public static class IterUtil
{
   public static IEnumerable<T> Iterate<T>(Func<bool> isEnded, Func<T> getItem)
   {
      if (isEnded())
         yield return getItem();
   }
}

これを使えば、こう書けます。

public static void Main()
{
   var fs = new FileStream("test.csv", FileMode.Open, FileAccess.Read);
   var sr = new StreamReader(fs, Encoding.GetEncoding("SHIFT_JIS"));

   foreach (Item item in IterUtil.Iterate(() => sr.EndOfStream, () => new Item(sr.ReadLine())))
   {
      // 何か処理
   }

   sr.Close();
   fs.Close();
}

いやまあ別にちゃんと動いてるならwhile文のままでいいだろって話もあるのですが、
やっぱりLINQ&foreachの方が「列挙してる」って感じで好きなのです。