2

このコードはコンパイルされておらず、次のエラーがスローされています。

タイプ 'TestesInterfaces.MyCollection' には既に 'Current' の定義が含まれています

しかし、あいまいなメソッドを削除すると、他のエラーが発生し続けます。

誰でも助けることができますか?

public class MyCollection<T> : IEnumerator<T>
{
    private T[] vector = new T[1000];
    private int actualIndex;

    public void Add(T elemento)
    {
        this.vector[vector.Length] = elemento;
    }

    public bool MoveNext()
    {
        actualIndex++;
        return (vector.Length > actualIndex);
    }

    public void Reset()
    {
        actualIndex = -1;
    }

    void IDisposable.Dispose() { }

    public Object Current
    {
        get
        {
            return Current;
        }
    }


    public T Current
    {
        get
        {
            try
            {
                T element = vector[actualIndex];
                return element;
            }
            catch (IndexOutOfRangeException e)
            {
                throw new InvalidOperationException(e.Message);
            }
        }
    }
}
4

3 に答える 3

12

あなたは誤解していると思いますIEnumerator<T>。通常、コレクションはIEnumerable<T>ではなく を実装しIEnumerator<T>ます。次のように考えることができます。

  • クラスが を実装するときIEnumerable<T>、それは「私は列挙できるもののコレクションです」と述べています。
  • クラスが を実装するときIEnumerator<T>、それは「私は何かを列挙するものです」と述べています。

コレクションが を実装することはめったにありません (そしておそらく間違っています) IEnumerator<T>。そうすることで、コレクションを単一の列挙に制限しています。すでにコレクションをループしているコードのセグメント内でコレクションをループしようとした場合、または複数のスレッドでコレクションを同時にループしようとした場合、コレクション自体が列挙操作の状態。通常、コレクション (実装IEnumerable<T>) は個別のオブジェクト (実装) を返し、IEnumerator<T>その個別のオブジェクトは列挙操作の状態を格納する役割を果たします。したがって、各列挙操作は個別のオブジェクトによって表されるため、任意の数の同時列挙またはネストされた列挙を使用できます。

foreachまた、ステートメントが機能するためには、inキーワードの後のオブジェクトがorを実装する必要があります。オブジェクトがorのみを実装している場合は機能しません。IEnumerableIEnumerable<T>IEnumeratorIEnumerator<T>

これがあなたが探しているコードだと思います:

public class MyCollection<T> : IEnumerable<T>
{
    private T[] vector = new T[1000];
    private int count;

    public void Add(T elemento)
    {
        this.vector[count++] = elemento;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return vector.Take(count).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
于 2013-08-07T13:46:31.577 に答える
1

C# 2.0 以降では、イテレータを実装する非常に簡単な方法があり、コンパイラはステート マシンを作成することで舞台裏で多くの面倒な作業を行っていると思います。それを調べる価値があります。そうは言っても、その場合、実装は以下のようになります。

    public class MyCollection<T>
    {
        private T[] vector = new T[1000];
        private int actualIndex;

        public void Add(T elemento)
        {
            this.vector[vector.Length] = elemento;
        }

        public IEnumerable<T> CreateEnumerable()
        {
          for (int index = 0; index < vector.Length; index++)
          {
            yield return vector[(index + actualIndex)];
          }
       }
   }

ただし、actualIndex の目的についてはよくわかりませんが、理解していただければ幸いです。

MyCollection を適切に初期化した後、消費者の観点から見たスニペットを以下に示します。

MyCollection<int> mycoll = new MyCollection<int>();
            foreach (var num in mycoll.CreateEnumerable())
            {
                Console.WriteLine(num);
            }
于 2018-02-14T18:08:55.987 に答える