誰かがforeach
キーワードをカスタムオブジェクトで使用する簡単な例を共有できますか?
タグを考えると、あなたは.NETを意味していると思いますが、私が知っているのはC#について話すことです。
foreach
ステートメントは(通常)IEnumerable
とIEnumerator
またはそれらの一般的ないとこを使用します。フォームのステートメント:
foreach (Foo element in source)
{
// Body
}
ここで、source
はIEnumerable<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
}
}
(ここでは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);