Search code examples
c#ienumerableenumerate

Why doesn't the following work? (IEnumerable/ IEnumerator)


I was trying out the example on this MSDN page. I tried to change the GetEnumerator method. I know something doesn't seem right in that, but it complies and then doesn't run. Error is that the Enumerator has not started and that MoveNext should be called, but it is being called!

class Program
{
    static void Main(string[] args)
    { 
        foreach (var day in new DaysOfTheWekk())
        {
            Console.WriteLine(day) ;
        }
        Console.ReadLine();
    }
}

public class DaysOfTheWekk: IEnumerable
{
    private string[] days = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

    public IEnumerator GetEnumerator()
    {
        days.GetEnumerator().MoveNext();
        yield return days.GetEnumerator().Current;
    }
}

Solution

  • Why do you want to call moveNext? Just leave out the .Current:

    public class DaysOfTheWeek: IEnumerable
    {
        private string[] days = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    
        public IEnumerator GetEnumerator()
        {
            return days.GetEnumerator();
        }
    }
    

    Otherwise use a while loop since:

    public class DaysOfTheWeek: IEnumerable
    {
        private string[] days = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    
        public IEnumerator GetEnumerator()
        {
            var enumerator = days.GetEnumerator();
            while(enumerator.MoveNext())
            { 
                yield return enumerator.Current;
            }
        }
    }
    

    Explanation: The GetEnumerator() method always returns a new enumerator, so if you call GetEnumerator().Current, then the MoveNext() function has not been called on the newly returned instance! Use a variable as stated in my second example, instead.