簡體   English   中英

我該如何實現IEnumerator <T> ?

[英]How can I implement IEnumerator<T>?

此代碼未編譯,它拋出以下錯誤:

'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);
            }
        }
    }
}

您需要定義當前正在實現的接口。

Object IEnumerator.Current
{
    //
}

public T Current
{
    //
}

這樣你的類就有2個Current屬性。 但你可以訪問它們。

MyCollection<string> col = new MyCollection<string>();
var ienumeratort = col.Current; //Uses IEnumerator<T>
var ienumerator = (IEnumerator)col.Current; //uses IEnumerator

我認為你誤解了IEnumerator<T> 通常,集合實現IEnumerable<T> ,而不是IEnumerator<T> 你可以這樣想:

  • 當一個類實現IEnumerable<T> ,它聲明“我是可以枚舉的東西的集合”。
  • 當一個類實現IEnumerator<T> ,它表示“我是一個枚舉某事的東西”。

實現IEnumerator<T>的集合很少(也可能是錯誤的)。 通過這樣做,您將集合限制為單個枚舉。 如果您嘗試在已經循環遍歷集合的代碼段中循環遍歷集合,或者如果您嘗試同時在多個線程上遍歷集合,則無法執行此操作,因為您的集合本身正在存儲枚舉操作的狀態。 通常,集合(實現IEnumerable<T> )返回一個單獨的對象(實現IEnumerator<T> ),並且該單獨的對象負責存儲枚舉操作的狀態。 因此,您可以擁有任意數量的並發或嵌套枚舉,因為每個枚舉操作都由不同的對象表示。

另外,為了使foreach語句起作用, in關鍵字之后的對象必須實現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();
    }
}

我認為從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);
            }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM