C # IEnumerable, IEnumerator Reset Function does not receive a call

I try so that my class can iterate through with foreach. I have read this lesson. The MSDN . It seems very direct. However, I have a problem when I want to repeat a second time. I debugged it; and it turned out that it does not call the function Reset().

Class A

class A : IEnumerable, IEnumerator
{
    int[] data = { 0, 1, 2, 3, 4 };

    int position = -1;

    public object Current
    {
        get
        {
            return data[position];
        }
    }

    public bool MoveNext()
    {
        position++;
        return (position < data.Length);
    }

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

    public IEnumerator GetEnumerator()
    {
        return (IEnumerator)this;
    }
}

When I run the next main function; it never calls a function Reset(). So, after one cycle, I can never repeat my class again.

home

static void Main(string[] args)
{
    A a = new A();

    foreach (var item in a)
    {
        Console.WriteLine(item);
    }

    Console.WriteLine("--- First foreach finished. ---");

    foreach (var item in a)
    {
        Console.WriteLine(item);
    }
}

Conclusion:

0
1
2
3
4
--- First foreach finished. ---
Press any key to continue . . .

Any thoughts?

+5
source share
4 answers

, foreach, IEnumerator. - - IEnumerator .

() . A ( data) position . , foreach.

, , - :

using System;
using System.Collections;

class A : IEnumerable
{
    int[] data = { 0, 1, 2, 3, 4 };

    public IEnumerator GetEnumerator()
    {
        return new AEnumerator(this);
    }

    private class AEnumerator : IEnumerator
    {
        public AEnumerator(A inst)
        {
            this.instance = inst;
        }

        private A instance;
        private int position = -1;

        public object Current
        {
            get
            {
                return instance.data[position];
            }
        }

        public bool MoveNext()
        {
            position++;
            return (position < instance.data.Length);
        }

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

    }
}

, ( , ):

class A : IEnumerable
{
    int[] data = { 0, 1, 2, 3, 4 };

    public IEnumerator GetEnumerator()
    {
        return data.GetEnumerator();
    }
}

, , :

class A : IEnumerable
{
    int[] data = { 0, 1, 2, 3, 4 };

    public IEnumerator GetEnumerator()
    {
        for (int i=0;i<data.Length;++i)
           yield return data[i];
    }
}

IEnumerable<int> IEnumerable. .

+11

Reset. , , , (.. IEnumerable IEnumerator), :

public class StackOverflow_11475328
{
    class A : IEnumerable
    {
        int[] data = { 0, 1, 2, 3, 4 };

        public IEnumerator GetEnumerator()
        {
            return new AEnumerator(this);
        }

        class AEnumerator : IEnumerator
        {
            private A parent;
            private int position = -1;

            public AEnumerator(A parent)
            {
                this.parent = parent;
            }

            public object Current
            {
                get { return parent.data[position]; }
            }

            public bool MoveNext()
            {
                position++;
                return (position < parent.data.Length);
            }

            public void Reset()
            {
                position = -1;
            }
        }
    }
    public static void Test()
    {
        A a = new A();

        foreach (var item in a)
        {
            Console.WriteLine(item);
        }

        Console.WriteLine("--- First foreach finished. ---");

        foreach (var item in a)
        {
            Console.WriteLine(item);
        }
    }
}
+4

Reset() . , : GetEnumerator().

, ( ) , , , , : . , [] API!

, . , . ( ) , , , . , ToList(), .

"foreach" Reset() . GetEnumerator(), MoveNext(), Current Dispose().

+4
source

Both Reed and Carlos are true. Here's how you can do it, since it int[]implements IEnumerableandIEnumerable<int>

class A : IEnumerable
{ 
    int[] data = { 0, 1, 2, 3, 4 }; 

    public IEnumerator GetEnumerator() 
    { 
        return data.GetEnumerator(); 
    } 
} 

Or, to be more strongly typed, you can use the general form IEnumerable:

class A : IEnumerable<int>
{
    int[] data = { 0, 1, 2, 3, 4 };

    public IEnumerator<int> GetEnumerator()
    {
        return ((IEnumerable<int>)data).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return data.GetEnumerator();
    }
}
0
source

All Articles