|
|
連載:[完全版]究極のC#プログラミング
Chapter3 新しい繰り返しのスタイル ― yield return文とForEachメソッド
川俣 晶
2009/08/31 |
 |
|
3.9 catchできない制約
yield return文に慣れると、リスト3.8のようなコードを書いてみるプログラマーも出てくると思う。
using System;
using System.Collections.Generic;
using System.IO;
class Program
{
private static IEnumerable<string> readTextFile(string filename)
{
StreamReader reader = File.OpenText(filename);
try
{
for (; ; )
{
string s = reader.ReadLine();
if (s == null) break;
yield return s;
}
}
catch (IOException e)
{
Console.WriteLine(e.ToString());
}
finally
{
reader.Close();
}
}
static void Main(string[] args)
{
foreach (string s in readTextFile(@"c:\test.txt"))
{
Console.WriteLine(s);
}
}
}
|
|
リスト3.8 コンパイルできない例 |
だが、このコードはコンパイルできない。
catch 句を含む try ブロックの本体で値を生成することはできません。
というエラーが出てしまうからだ。
実は、yield return文は、例外処理のためのtry〜catch構文の中で使用できないという制約を持つ。制約があるのはこの組み合わせだけである。たとえば、yield break文をtry〜catch構文の中で使用することはできるし、yield return文は、try〜finally構文の中で使用することができる。
そこで、yield return文のみ、try〜catch構文から外すように書き直したのがリスト3.9である。
using System;
using System.Collections.Generic;
using System.IO;
class Program
{
private static IEnumerable<string> readTextFile(string filename)
{
StreamReader reader = File.OpenText(filename);
try
{
for (; ; )
{
string s;
try
{
s = reader.ReadLine();
}
catch (IOException e)
{
Console.WriteLine(e.ToString());
yield break;
}
if (s == null) break;
yield return s;
}
}
finally
{
reader.Close();
}
}
static void Main(string[] args)
{
// 実行時にはテキストファイル「c:\test.txt」が必要
foreach (string s in readTextFile(@"c:\test.txt"))
{
Console.WriteLine(s);
}
}
}
|
|
リスト3.9 リスト3.8をコンパイル可能に修正した例 |
見てのとおり、かなり回りくどくなったが、同じ意図を記述することはできる。
Insider.NET 記事ランキング
本日
月間