Effective C# 3rd 読書メモ 31 合成可能なAPIを作る

イテレーターメソッドの結果を次のイテレーターメソッドにつなげるような呼び出しを行うと、イテレーターは全体で1回だけ実行される(遅延評価される)。

public static void Main(string[] args)
{
    var nums = new[] {1, 2, 2, 3};
    foreach (var num in Square(Unique(nums)))
    {
        WriteLine(num);
    }
}

public static IEnumerable<T> Unique<T>(IEnumerable<T> sequence)
{
    var uniqueVals = new HashSet<T>();
    foreach (var item in sequence)
    {
        WriteLine($"Unique: {item.ToString()}");
        if (uniqueVals.Contains(item)) continue;
        uniqueVals.Add(item);
        yield return item;
    }
}

public static IEnumerable<int> Square(IEnumerable<int> nums)
{
    foreach (var num in nums)
    {
        WriteLine($"Square: {num.ToString()}");
        yield return num * num;
    }
}

上記コードを実行すると、その出力は以下のようになる。「{1, 2, 2, 3}」という配列を前から順に1回だけ走査していることがわかる。

Unique: 1
Square: 1
1
Unique: 2
Square: 2
4
Unique: 2
Unique: 3
Square: 3
9

このように、イテレーターメソッドを使うと、通常のループに比べて、関数を合成するような使い方ができる。

コメントを残す

コメントを残す