SSブログ

[.NET]yield returnの使用例(C#) [Programming .NET Tips]

[はじめに]
 C#には「yield」キーワードがありますが、
 他の言語と比べて特殊でわかりにくいので、使い方の備忘録を掲載します。
 ※「yield」は、
  他の言語(JavaScript、Perl、Python等)でも採用されつつありますが。。。

 「yield」は、
 オブジェクト指向のデザインパターンのIteratorパターンの実装で利用されます。
 Iteratorパターンとは、多数の集合に対してその内部の実装を意識することなく、
 逐次処理するためのデザインパターンです。

 C#では、.NET Framework 2.0(Visual Studio 2005)から
 「yield」が導入されました。
 .NET Framework 1.1(Visual Studio .NET 2003)以前の版で、
 Iteratorパターンを実装するには、
 IEnumerableインタフェース、IEnumeratorインタフェースを実装したクラスを
 記述する必要がありましたが、
 .NET Framework 2.0(Visual Studio 2005)以降では、
 それらのクラスは「yield return」で代用され、
 Iteratorパターンの実装がより簡潔になりました。

[サンプルコード]
以下、2つのサンプルコードを掲載します。
2つのサンプルコードは、各々独立して動作します。
 /// <summary>
 /// yield returnの実装サンプル
 /// </summary>
 public class YieldSample1 : IEnumerable<string>
 {
     /// <summary>
     /// 月の異名の列挙を取得する。
     /// </summary>
     /// <returns>月の異名の列挙</returns>
     public IEnumerator<string> GetEnumerator()
     {
         yield return "睦月";
         yield return "如月";
         yield return "弥生";
         yield return "卯月";
         yield return "皐月";
         yield return "水無月";
         yield return "葉月";
         yield return "長月";
         yield return "神無月";
         yield return "霜月";
         yield return "師走";
     }

     /// <summary>
     /// 月の異名の列挙を取得する。
     /// </summary>
     /// <returns>月の異名</returns>
     IEnumerator IEnumerable.GetEnumerator()
     {
         return this.GetEnumerator();
     }
 }

 public class Program1
 {
     /// <summary>
     /// 列挙を取得し、各々の要素を出力する。
     /// </summary>
     /// <param name="args"></param>
     static void Main(string[] args)
     {
         System.Console.WriteLine("■月の異名を出力する。");

         IEnumerable<string> ie1 = new YieldSample1();
         foreach (var it1 in ie1)
         {
             System.Console.WriteLine(it1);
         }
         System.Console.WriteLine("");

         //[出力]
         // ■月の異名を出力する。
         // 睦月
         // 如月
         // 弥生
         // 卯月
         // 皐月
         // 水無月
         // 葉月
         // 長月
         // 神無月
         // 霜月
         // 師走

         //[補足]
         // 上記コードは、
         // 下記のように書き換えることも可能です。
         // 逆に言うと、foreachで実装すると、
         // 以下のコードに読み替えて実行されます。

         //System.Console.WriteLine("■月の異名を出力する。(while文で処理)");

         //IEnumerable<string> ie1 = new YieldSample1();
         //IEnumerator<string> it1 = ie1.GetEnumerator();
         //while (it1.MoveNext())
         //{
         //    System.Console.WriteLine(it1.Current);
         //}
         //System.Console.WriteLine("");

         System.Console.ReadLine();

     }
 }
[C#]yield returnの使用例(その2)


/// <summary>
/// yield returnの実装サンプル
/// </summary>
public class YieldSample2
{
    /// <summary>
    /// 干支の列挙を取得する。
    /// </summary>
    /// <returns>干支の列挙</returns>
    public IEnumerable<String> GetEto()
    {
        yield return "子年";
        yield return "丑年";
        yield return "寅年";
        yield return "卯年";
        yield return "辰年";
        yield return "巳年";
        yield return "午年";
        yield return "未年";
        yield return "申年";
        yield return "酉年";
        yield return "戌年";
        yield return "亥年";
    }
}

public class Program2
{
    /// <summary>
    /// 列挙を取得し、各々の要素を出力する。
    /// </summary>
    /// <param name="args"></param>
    static void Main(string[] args)
    {
        System.Console.WriteLine("■干支を出力する。");

        YieldSample2 ie1 = new YieldSample2();
        foreach (var it1 in ie1.GetEto())
        {
            System.Console.WriteLine(it1);
        }
        System.Console.WriteLine("");

        //[出力]
        // ■干支を出力する。
        // 子年
        // 丑年
        // 寅年
        // 卯年
        // 辰年
        // 巳年
        // 午年
        // 未年
        // 申年
        // 酉年
        // 戌年
        // 亥年

        //[補足]
        // 上記コードは、
        // 下記のように書き換えることも可能です。
        // 逆に言うと、foreachで実装すると、
        // 以下のコードに読み替えて実行されます。

        //System.Console.WriteLine("■干支を出力する。(while文で処理)");

        //YieldSample2 ie1 = new YieldSample2();
        //IEnumerator<string> it1 = ie1.GetEto().GetEnumerator();
        //while (it1.MoveNext())
        //{
        //    System.Console.WriteLine(it1.Current);
        //}
        //System.Console.WriteLine("");

        System.Console.ReadLine();
    }
}
[C#]yield returnの使用例(その2)


[ご参考]
Iteratorパターンについて
 デザインパターン「Iterator」-Qiita


nice!(0)  コメント(0) 
共通テーマ:パソコン・インターネット

nice! 0

コメント 0

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。