web-dev-qa-db-ja.com

IEnumeratorとIEnumerableの違いは何ですか?

可能性のある複製:
誰でもIEnumerableとIEnumeratorを説明できますか?

IEnumeratorとIEnumerableの違いは何ですか?

95
Shaun

IEnumerable は、1つのメソッドを定義するインターフェイスですGetEnumeratorは、IEnumeratorインターフェイスを返します。コレクション。 IEnumerableを実装するコレクションは、foreachステートメントで使用できます。

定義

IEnumerable 

public IEnumerator GetEnumerator();

IEnumerator

public object Current;
public void Reset();
public bool MoveNext();

codebetter.comのサンプルコード

107
cgreeno

IEnumeratorは列挙可能なものです。CurrentプロパティとMoveNextおよびResetメソッド(.NETコードではおそらく明示的に呼び出されませんが、可能ですが)。

IEnumerableは列挙可能なものです...これは単に、IEnumeratorを返すGetEnumeratorメソッドがあることを意味します。

どちらを使用しますか? IEnumeratorを使用する唯一の理由は、非標準的な列挙方法(つまり、さまざまな要素を1つずつ返す)があり、その動作を定義する必要がある場合です。 IEnumeratorを実装する新しいクラスを作成します。ただし、IEnumeratorクラスのIEnumerableを返す必要があります。

列挙子(IEnumerator<T>を実装)の外観については、Enumerator<T>List<T>、またはQueue<T>,に含まれるクラスなど、Stack<T>クラスを参照してください。 。 IEnumerableを実装するクラスについては、標準のコレクションクラスをご覧ください。

65
Ryan Lundy

Enumeratorは、リストまたはコレクション内のアイテムを示します。列挙子の各インスタンスは特定の位置(1番目の要素、7番目の要素など)にあり、その要素を提供する(IEnumerator.Current)か、次の要素に移動する(IEnumerator.MoveNext)ことができます。 C#でforeachループを記述すると、コンパイラは列挙子を使用するコードを生成します。

Enumerableは、Enumeratorsを提供できるクラスです。 GetEnumeratorというメソッドがあり、アイテムを見るEnumeratorを提供します。 C#でforeachループを記述すると、生成するコードはGetEnumeratorを呼び出して、ループで使用されるEnumeratorを作成します。

15
SLaks

IEnumerableIEnumeratorは両方ともインターフェースです。 IEnumerableには、GetEnumeratorというメソッドが1つだけあります。このメソッドは、すべてのメソッドがvoidを含む何かを返すため、インターフェイスである別のタイプを返し、そのインターフェイスはIEnumeratorです。コレクションクラスのいずれかに列挙子ロジックを実装する場合、IEnumerable(ジェネリックまたは非ジェネリック)を実装します。 IEnumerableには1つのメソッドしかありませんが、IEnumeratorには2つのメソッド(MoveNextおよびReset)とプロパティCurrentがあります。理解を容易にするために、IEnumerableをその中にIEnumeratorを含むボックスと考えてください(ただし、継承または包含によるものではありません)。理解を深めるためにコードを参照してください。

class Test : IEnumerable, IEnumerator
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }

    public object Current
    {
        get { throw new NotImplementedException(); }
    }

    public bool MoveNext()
    {
        throw new NotImplementedException();
    }

    public void Reset()
    {
        throw new NotImplementedException();
    }
}
9
James Kingsbery