C#におけるIEnumerableとIEnumeratorインターフェースの違いとは?
C#には、コレクションの列挙(走査)を扱うために、IEnumerableとIEnumeratorという2つの重要なインターフェースが用意されています。どちらも名前は似ていますが、役割が大きく異なります。本記事では、それぞれの特徴と違いを解説します。
IEnumerableインターフェースとは
IEnumerableは、IEnumeratorオブジェクトを返すGetEnumerator()メソッドを1つだけ定義するシンプルなインターフェースです。
このインターフェースを実装したクラスは、foreachステートメントを使用してコレクションを反復処理できるようになり、読み取り専用のアクセスが可能になります。
IEnumeratorインターフェースとは
一方、IEnumeratorはコレクションの要素を1つずつ順番に取得するための「列挙子」そのものを表すインターフェースです。以下の2つのメソッドと1つのプロパティを持っています。
- MoveNext():列挙子をコレクション内の次の要素へ進めます。次の要素が存在すれば
true、存在しなければfalseを返します。 - Reset():列挙子の位置をコレクションの先頭にリセットします。
- Current:現在位置にある要素を取得するためのプロパティです。
実装例
以下のコードは、IEnumerableとIEnumeratorの両方を実装したクラスの例です。
class Demo : IEnumerable, IEnumerator {
// IEnumerableメソッド GetEnumerator()
IEnumerator IEnumerable.GetEnumerator() {
throw new NotImplementedException();
}
public object Current {
get { throw new NotImplementedException(); }
}
// IEnumeratorメソッド
public bool MoveNext() {
throw new NotImplementedException();
}
// IEnumeratorメソッド
public void Reset() {
throw new NotImplementedException();
}
}上記の例では、IEnumeratorが持つ2つのメソッドであるMoveNext()とReset()が定義されていることが確認できます。
// IEnumeratorメソッド
public bool MoveNext() {
throw new NotImplementedException();
}
// IEnumeratorメソッド
public void Reset() {
throw new NotImplementedException();
}まとめ:両者の違い
- IEnumerable:コレクション自体が「列挙可能」であることを示し、
foreachによる反復処理を可能にします。 - IEnumerator:コレクションの要素を1つずつ順番に取り出すための列挙子であり、
MoveNext()・Reset()メソッドとCurrentプロパティを提供します。
つまり、IEnumerableは「列挙できること」を保証する入り口であり、IEnumeratorは実際に要素を順番にたどる仕組みを担っている、という関係性です。
-
GoとJavaの違いを徹底比較!特徴と使い分けのポイント
プログラミング言語を選ぶ際、「Go」と「Java」のどちらを採用すべきか迷う開発者は少なくありません。どちらもGoogleや企業システムで広く使われる人気言語ですが、設計思想や言語仕様には大きな違いがあります。本記事では、それぞれの言語の特徴を解説したうえで、両者の主な違いを比較表を使ってわかりやすく整理します。 GoとはGoはGoogleが開発した手続き型(プロシージャル)プログラミング言語です。プログラムはパッケージ単位で構成され、シンプルで読みやすいコード記述を重視した設計になっています。動的言語に近い柔軟なパターンを取り入れつつ、静的型付けによる安全性も兼ね備えています。また、軽量スレ
-
抽象クラスとインターフェースの違いを徹底解説
抽象クラスとインターフェースの違いとはJavaなどのオブジェクト指向プログラミング言語では、抽象クラスとインターフェースはどちらも「抽象的な型」を定義するために使用されます。しかし、両者には明確な違いがあり、適切に使い分けることがプログラム設計の質を大きく左右します。抽象クラスの特徴抽象クラスは、インスタンスメソッドとしてデフォルトの動作(具体的な実装)を持つことができます。そのため、複数の子クラスで共有する共通処理をあらかじめ実装しておくことが可能です。また、コンストラクタやインスタンスフィールド(状態)を持つこともできます。インターフェースの特徴一方、インターフェースは定数とインスタンスメ