Вопрос

I did below work

class Program
{
    class GenEnumerator<T> : IEnumerable
    {
        public T[] Values { get; set; }


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

    static void Main(string[] args)
    {
        GenEnumerator<string> g = new GenEnumerator<string>();
        g.Values = new string[] { "a", "b", "c", "d", "e" };
        g.GetEnumerator().MoveNext();

        Console.WriteLine(g.GetEnumerator().Current);


        Console.ReadKey();
    }
}

g.GetEnumerator().Current is always null.
but if I do this - var a = g.GetEnumerator();
the Current proeperty gets a value and works fine

Does it imply that I have to explicitly inherit the class from IEnumerator and implement its methods and property if I want to use Current without a IEnumerator type variable?

Thanks, Roy

Это было полезно?

Решение 2

This is because in order for the Current to become non-null, you need to call MoveNext() on the same object.

Your current code calls MoveNext() on a temporary object. Here is what's going on when you call

g.GetEnumerator().MoveNext()`;
Console.WriteLine(g.GetEnumerator().Current);
  • A call of GetEnumerator() returns an object x
  • A call x.MoveNext() is performed
  • x becomes eligible for garbage collection, because it is not referenced from any variable in your program.
  • When you call g.GetEnumerator().Current, a new object y is returned
  • A call to y.Current is made, returning null, because there was no call of MoveNext on object y

When you add a variable a, however, you call MoveNext and Current on the same object, fixing the problem:

  • A call of GetEnumerator() returns an object x, which is assigned to variable a
  • A call a.MoveNext() is performed
  • A call a.Current is performed

Другие советы

You're creating new instances of GenEnumerator everytime by calling GetEnumerator, that's why your Current is null. Instead store it in a field and use that.

var e = g.GetEnumerator();
if(e.MoveNext())
{
    var current = e.Current;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top