web-dev-qa-db-ja.com

C#のカスタムオブジェクトでforeachキーワードを使用する方法

誰かがforeachキーワードをカスタムオブジェクトで使用する簡単な例を共有できますか?

19
user42070

タグを考えると、あなたは.NETを意味していると思いますが、私が知っているのはC#について話すことです。

foreachステートメントは(通常)IEnumerableIEnumeratorまたはそれらの一般的ないとこを使用します。フォームのステートメント:

foreach (Foo element in source)
{
    // Body
}

ここで、sourceIEnumerable<Foo>を実装しますおおまかにと同等です:

using (IEnumerator<Foo> iterator = source.GetEnumerator())
{
    Foo element;
    while (iterator.MoveNext())
    {
        element = iterator.Current;
        // Body
    }
}

IEnumerator<Foo>は最後に破棄されますが、ステートメントは終了することに注意してください。これはイテレータブロックにとって重要です。

IEnumerable<T>またはIEnumerator<T>を自分で実装するには、イテレータブロックを使用するのが最も簡単な方法です。ここにすべての詳細を書くのではなく、無料でダウンロードできる C#の第6章の詳細 を参照することをお勧めします。第6章全体はイテレータに関するものです。 DepthサイトのC#にもいくつかの記事があります。

ただし、簡単な例として:

public IEnumerable<int> EvenNumbers0To10()
{
    for (int i=0; i <= 10; i += 2)
    {
        yield return i;
    }
}

// Later
foreach (int x in EvenNumbers0To10())
{
    Console.WriteLine(x); // 0, 2, 4, 6, 8, 10
}

型にIEnumerable<T>を実装するには、次のようにします。

public class Foo : IEnumerable<string>
{
    public IEnumerator<string> GetEnumerator()
    {
        yield return "x";
        yield return "y";
    }

    // Explicit interface implementation for nongeneric interface
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator(); // Just return the generic version
    }
}
41
Jon Skeet

(ここではC#を想定しています)

カスタムオブジェクトのリストがある場合は、他のオブジェクトと同じようにforeachを使用できます。

List<MyObject> myObjects = // something
foreach(MyObject myObject in myObjects)
{
     // Do something nifty here
}

独自のコンテナーを作成する場合は、yieldキーワード(.Net 2.0以降)をIEnumerableインターフェイスと一緒に使用できます。

class MyContainer : IEnumerable<int>
{
    private int max = 0;
    public MyContainer(int max)
    {
        this.max = max;
    }

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

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

そして、foreachでそれを使用します:

MyContainer myContainer = new MyContainer(10);
foreach(int i in myContainer)
    Console.WriteLine(i);
7