How would you implement the IEnumerator interface?

前端 未结 5 1298
一生所求
一生所求 2020-12-03 03:58

I have a class that map objects to objects, but unlike dictionary it maps them both ways. I am now trying to implement a custom IEnumerator interface that iterates through t

相关标签:
5条回答
  • 2020-12-03 04:23

    Here's an example from the book "Algorithms (4th Edition) by Robert Sedgewick".

    It was written in java and i basically rewrote it in C#.

    public class Stack<T> : IEnumerable<T>
    {
        private T[] array;
    
        public Stack(int n)
        {
            array = new T[n];
        }
    
        public Stack()
        {
            array = new T[16];
        }
    
        public void Push(T item)
        {
            if (Count == array.Length)
            {
                Grow(array.Length * 2);
            }
    
            array[Count++] = item;
        }
    
        public T Pop()
        {
            if (Count == array.Length/4)
            {
                Shrink(array.Length/2);
            }
    
            return array[--Count];
        }
    
        private void Grow(int size)
        {
            var temp = array;
            array = new T[size];
            Array.Copy(temp, array, temp.Length);
        }
    
        private void Shrink(int size)
        {
            Array temp = array;
            array = new T[size];
            Array.Copy(temp,0,array,0,size);
        }
    
        public int Count { get; private set; }
        public IEnumerator<T> GetEnumerator()
        {
            return new ReverseArrayIterator(Count,array);
        }
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    
    
        // IEnumerator implementation
        private class ReverseArrayIterator : IEnumerator<T>
        {
            private int i;
    
            private readonly T[] array;
    
            public ReverseArrayIterator(int count,T[] array)
            {
                i = count;
                this.array = array;
            }
    
            public void Dispose()
            {
    
            }
    
            public bool MoveNext()
            {
                return i > 0;
            }
    
            public void Reset()
            {
    
            }
    
            public T Current { get { return array[--i]; } }
    
            object IEnumerator.Current
            {
                get { return Current; }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-03 04:31

    CreateEnumerable() returns an IEnumerable which implements GetEnumerator()

    public class EasyEnumerable : IEnumerable<int> {
    
        IEnumerable<int> CreateEnumerable() {
            yield return 123;
            yield return 456;
            for (int i = 0; i < 6; i++) {
                yield return i;
            }//for
        }//method
    
        public IEnumerator<int> GetEnumerator() {
            return CreateEnumerable().GetEnumerator();
        }//method
    
        IEnumerator IEnumerable.GetEnumerator() {
            return CreateEnumerable().GetEnumerator();
        }//method
    
    }//class
    
    0 讨论(0)
  • 2020-12-03 04:33

    Just implement the IEnumerable interface, no need to implement the IEnumerator unless you want to do some special things in the enumerator, which for your case doesn't seem to be needed.

    public class Mapper<K,T> : IEnumerable<T> {
        public IEnumerator<T> GetEnumerator()
        {
            return KToTMap.Values.GetEnumerator();
        }
    }
    

    and that's it.

    0 讨论(0)
  • 2020-12-03 04:41

    Use yield return.

    What is the yield keyword used for in C#?

    0 讨论(0)
  • 2020-12-03 04:42

    First, don't make your collection object implement IEnumerator<>. This leads to bugs. (Consider the situation where two threads are iterating over the same collection).

    Implementing an enumerator correctly turns out to be non-trivial, so C# 2.0 added special language support for doing it, based on the 'yield return' statement.

    Raymond Chen's recent series of blog posts ("The implementation of iterators in C# and its consequences") is a good place to get up to speed.

    • Part 1: https://web.archive.org/web/20081216071723/http://blogs.msdn.com/oldnewthing/archive/2008/08/12/8849519.aspx
    • Part 2: https://web.archive.org/web/20080907004812/http://blogs.msdn.com/oldnewthing/archive/2008/08/13/8854601.aspx
    • Part 3: https://web.archive.org/web/20080824210655/http://blogs.msdn.com/oldnewthing/archive/2008/08/14/8862242.aspx
    • Part 4: https://web.archive.org/web/20090207130506/http://blogs.msdn.com/oldnewthing/archive/2008/08/15/8868267.aspx
    0 讨论(0)
提交回复
热议问题