foreach
カスタムオブジェクトでキーワードを使用する簡単な例を共有できますか?
3 に答える
タグを考えると、.NET のことを意味していると思います。C# について話すことにします。C# については知っているからです。
foreach
ステートメントは (通常)およびIEnumerable
またはIEnumerator
それらの一般的な従兄弟を使用します。次の形式のステートメント:
foreach (Foo element in source)
{
// Body
}
ここで、source
implementsIEnumerable<Foo>
は次とほぼ同等です。
using (IEnumerator<Foo> iterator = source.GetEnumerator())
{
Foo element;
while (iterator.MoveNext())
{
element = iterator.Current;
// Body
}
}
IEnumerator<Foo>
は最後に破棄されますが、ステートメントは終了することに注意してください。これは、反復子ブロックにとって重要です。
自分で実装IEnumerable<T>
するIEnumerator<T>
には、イテレータ ブロックを使用するのが最も簡単な方法です。ここにすべての詳細を記述するよりも、無料でダウンロードできるC# in Depth の第 6 章を参照することをお勧めします。第6章全体がイテレータについてです。私の C# in Depth サイトにも、次の 2 つの記事があります。
ただし、簡単な例として:
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);