連載:[完全版]究極のC#プログラミング

Chapter3 新しい繰り返しのスタイル ― yield return文とForEachメソッド

川俣 晶
2009/08/31

3.7 1つのクラスに複数の列挙機能を付ける

 クラスライブラリのDictionaryクラス(System.Collections.Generic名前空間)はそれ自身が列挙可能であると同時に、列挙可能なKeysプロパティやValuesプロパティを持っている。こういったクラスを反復子で実装するのも簡単である。

 リスト3.6は、配列をそのままの順番で列挙するGetEnumeratorメソッドと、逆順で列挙するGetReverseOrderメソッドを提供するクラスの例である。

using System;
using System.Collections.Generic;

class Sample
{
  private int[] array = { 1, 2, 3 };

  public IEnumerator<int> GetEnumerator()
  {
    for (int i = 0; i < array.Length; i++)
    {
      yield return i;
    }
  }

  public IEnumerable<int> GetReverseOrder()
  {
    for (int i = array.Length - 1; i >= 0 ; i--)
    {
      yield return i;
    }
  }
}

class Program
{
  static void Main(string[] args)
  {
    foreach (int i in new Sample())
    {
      Console.WriteLine(i);
    }
    // 出力:
    // 0
    // 1
    // 2

    foreach (int i in new Sample().GetReverseOrder())
    {
      Console.WriteLine(i);
    }
    // 出力:
    // 2
    // 1
    // 0
  }
}
リスト3.6 反復子で複数の列挙機能を持つクラスを作る

 ここでは、GetEnumeratorメソッドはforeach文内で明示的に書く必要はないが、GetReverseOrderメソッドは明示的に名前を書く必要があることに留意しよう。

 また、このリスト3.6には、1つだけ注意点がある。それは、GetEnumeratorメソッドの戻り値の型はIEnumerator<int>型であるのに対して、GetReverseOrderメソッドはIEnumerable<int>型になっているという点である。

 GetEnumeratorメソッドとGetReverseOrderメソッドは、ソースコードだけ見ているとよく似た兄弟に見えるが、foreach文から見ると扱いがまったく別個なのである。foreach文は通常、IEnumerable<T>型のオブジェクトを受け取って処理するが、特定の型を返すGetEnumeratorという名前のpublicなメソッドは、それだけで列挙可能と見なされるのである。


 INDEX
  [完全版]究極のC#プログラミング
  Chapter3 新しい繰り返しのスタイル ― yield return文とForEachメソッド
    1.3.1 「繰り返し」という古くて新しい問題
    2.3.2 数を数えるというサンプル
    3.3.3 C# 1.xによるRangeクラスの実装
    4.3.4 C# 3.0によるRangeクラスの実装
    5.3.5 yield break文による中断
    6.3.6 yieldは予約語ではない
  7.3.7 1つのクラスに複数の列挙機能を付ける
    8.3.8 自動的に作られるオブジェクトと二重利用
    9.3.9 catchできない制約
    10.3.10 制約の真相―見た目と違う真実の姿
    11.3.11 ForEachメソッドを使う別解
    12.3.12 性能比較
 
インデックス・ページヘ  「[完全版]究極のC#プログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間