【C#】イテレーターとは(基本、使い方)
イテレーターは、コレクションまたはシーケンスの要素を一つずつ返す方法を提供します。これにより、コレクションの全体をメモリに保持することなく、要求されたときに各要素を生成して返すことができます。
イテレーター
イテレーターを使用する主な利点は、効率的なリソース利用と、コレクションの処理をより柔軟に行えることです。yield return
ステートメントを使うと、メソッドの実行を一時停止し、現在の呼び出しコンテキストを保持した状態で値を呼び出し元に返すことができます。その後、次の要素が要求されると、メソッドは停止した場所から実行を再開します。
イテレーターは、foreach
ループなど、コレクションを一つずつ走査するシナリオで特に有用です。イテレーターメソッドやプロパティは、IEnumerable
インターフェースや IEnumerable<T>
インターフェースを実装することで、任意のコレクション型に対して動作します。これにより、カスタムの反復処理を簡単に実装でき、コードの再利用性と可読性が向上します。
サンプル
yield return
を使った一般的な用途は、条件に基づいてフィルターされた要素のシーケンスを生成することです。以下の例では、特定の条件(この場合は偶数のみを対象とする)に一致する数値のみを返すメソッドを作成します。
偶数のみを返すシンプルな例
// 1から10までの偶数を出力します
foreach (var number in EvenNumbers(10))
{
Console.WriteLine(number);
}
// 指定された上限までの偶数を生成するメソッド
IEnumerable<int> EvenNumbers(int limit)
{
for (int i = 1; i <= limit; i++)
{
if (i % 2 == 0)
{
yield return i;
}
}
}
この例では、EvenNumbers
メソッドは1からlimit
までの整数をループし、各数値が偶数かどうかを確認します。偶数の場合、その数値はyield return
によって返されます。これにより、メソッドの呼び出し元は偶数のみを含むシーケンスを受け取ります。
yield return
を使用することで、メソッドの呼び出し元はメソッドが完全に終了するのを待つことなく、結果を逐次的に受け取ることができます。これは、リソースを節約し、アプリケーションのパフォーマンスを向上させるのに役立ちます。また、大量のデータを扱う際にメモリ使用量を削減する効果もあります。
実行結果
2
4
6
8
10
IEnumerableについて
IEnumerable
とIEnumerable<T>
は、C#のSystem.Collections名前空間にあるインターフェースで、コレクションや配列などのシーケンスを反復処理するための標準的な方法を提供します。これらのインターフェースを実装することで、コレクション内の各要素を一つずつ順番にアクセスできるようになります。主にforeach
ループでの使用を目的としています。
IEnumerable
インターフェース
IEnumerable
は、非ジェネリックなコレクションに対して使用されます。- このインターフェースには、
GetEnumerator
メソッドが定義されています。このメソッドは、IEnumerator
インターフェースを実装するオブジェクトを返します。 IEnumerator
オブジェクトを使用して、コレクションを反復処理し、コレクション内の現在の要素を取得し、次の要素に移動します。
IEnumerable<T>
インターフェース
IEnumerable<T>
は、ジェネリックなコレクションに対して使用されるインターフェースで、IEnumerable
のジェネリック版です。- ジェネリックな
IEnumerable<T>
インターフェースも、GetEnumerator
メソッドを定義していますが、このメソッドはIEnumerator<T>
インターフェースを実装するオブジェクトを返します。 IEnumerator<T>
はジェネリックなIEnumerator
インターフェースであり、型安全な方法でコレクションを反復処理することができます。
使用例
IEnumerable
またはIEnumerable<T>
を実装するクラスは、以下のようにforeach
ループで簡単に反復処理することができます。
IEnumerable<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{
Console.WriteLine(number);
}
この例では、List<int>
がIEnumerable<int>
を実装しているため、foreach
ループを使ってリストの各要素を順に処理できます。
まとめ
IEnumerable
とIEnumerable<T>
インターフェースは、コレクションを扱う際の非常に重要な部分です。これらを理解し、適切に利用することで、C#におけるコレクションの反復処理がより効率的で柔軟になります。また、これらのインターフェースを利用することで、カスタムコレクションでもforeach
ループを使用できるようになり、コードの可読性と保守性が向上します。
IEnumeratorについて
IEnumerator
とIEnumerator<T>
は、C#のSystem.CollectionsおよびSystem.Collections.Generic名前空間にあるインターフェースで、コレクション内の要素を順番に列挙するための機構を提供します。これらはIEnumerable
やIEnumerable<T>
インターフェースと密接に関連しており、コレクションを一つずつ反復処理する際に使用されます。
IEnumerator
インターフェース
IEnumerator
は、非ジェネリックなコレクションを反復処理するためのインターフェースです。- 主なメンバーは以下の通りです。
MoveNext()
: コレクションの次の要素に移動します。次の要素が存在する場合はtrue
を返し、そうでない場合はfalse
を返します。このメソッドは初めて呼び出されたときにコレクションの最初の要素の前に位置しています。Current
: コレクション内の現在の要素を取得します。このプロパティはobject
型の値を返します。Reset()
: 列挙子を初期位置、つまりコレクションの最初の要素の前にリセットします。
IEnumerator<T>
インターフェース
IEnumerator<T>
は、IEnumerator
のジェネリック版で、型安全な方法でコレクションを反復処理するために使用されます。IEnumerator
と同様のメンバーを持ちますが、Current
プロパティはT
型の値を返します。これにより、キャストの必要性がなくなり、型安全性が確保されます。
使用例
IEnumerable
やIEnumerable<T>
インターフェースを実装するコレクションクラスは、内部的にIEnumerator
またはIEnumerator<T>
インターフェースを実装するオブジェクトをGetEnumerator
メソッドを通じて提供します。foreach
ループはこのメカニズムを利用してコレクションを反復処理しますが、直接IEnumerator
を使用することも可能です。
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
IEnumerator<int> enumerator = numbers.GetEnumerator();
while (enumerator.MoveNext())
{
int number = enumerator.Current;
Console.WriteLine(number);
}
この例では、List<T>
のGetEnumerator
メソッドを呼び出してIEnumerator<int>
を取得し、MoveNext
メソッドとCurrent
プロパティを使用してリストの各要素を反復処理しています。
まとめ
IEnumerator
とIEnumerator<T>
インターフェースは、コレクション内の要素を順にアクセスするための基本的なインターフェースです。これらは主にforeach
ループの背後で動作し、コレクションの反復処理を容易にします。また、これらのインターフェースを直接使用することで、コレクションのカスタム反復処理を実装することも可能です。
ディスカッション
コメント一覧
まだ、コメントがありません