RSS

Yield と IEnumerable, IEnumerator

30 11月

C#では yield return 文を使うと foreach 文の in 句に指定可能なレンジオブジェクトを作れます。Visual Basicでも Yield 文を使って同様のことができます。

C#では、IEnumerable インタフェースを実装したクラスのインスタンスが、in 句に指定可能なレンジオブジェクトになります。一方、Visual Basic では Iterator Function という関数がその代わりになります。この関数はIEnumerable(Of )を返す必要があります。

下のサンプルはC#で yield return を使うものですが、レンジオブジェクトになるクラス MyRange は IEnumerable を実装しています。IEnumerable は IEnumerator を返す GetEnumerator() メソッドを実装しなければなりません。このメソッドの中で、yield return を使って foreach 文で使われる項目を列挙します。

using System;
using System.Collections;

namespace Yield
{
  class MyRange : IEnumerable
  {
     object[] data;

     public MyRange()
     {
        data = new object[] { 100, "abc", -0.5, 0 };
     }
     public IEnumerator GetEnumerator()
     {
       int i = 0;
       while (i < data.Length)
       {
           i++;
           yield return data[i - 1];
       }
     }
  }
  class Program
  {
     static void Main(string[] args)
     {
        foreach (var x in new MyRange())
        {
            Console.WriteLine(x);
        }
#if DEBUG
        Console.ReadKey();
#endif
     }
   }
}

下のサンプルは Yield 文を使う Visual Basic の例です。C#ではIEnumerableインタフェースを実装したクラスを作成する必要がありましたが、Visual Basic では Iterator Function という関数を定義するだけです。
この関数は IEnumerable(Of ) 型を返し、その関数値は Yield文で列挙します。

' Yieldのテスト (Visual Basic)
Module Module1
Sub Main()
 For Each i In MyRange()
   Console.WriteLine(i)
 Next
 #If DEBUG Then
   Console.ReadKey()
 #End If
End Sub

Iterator Function MyRange() As IEnumerable(Of Integer)
   For i = 1 To 20 Step 3
     Yield i
   Next
End Function
End Module
 
コメントする

投稿者: : 2012/11/30 投稿先 C#, VB

 

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

 
%d人のブロガーが「いいね」をつけました。