当我实现IEnumerable时,为什么我不能得到Current的值?

时间:2014-01-08 09:27:01

标签: c# .net ienumerable

我做了以下工作

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始终为空。
但如果我这样做 - var a = g.GetEnumerator();
当前的proeperty得到一个值并且工作正常

如果我想在没有IEnumerator类型变量的情况下使用Current,是否必须明确继承IEnumerator中的类并实现其方法和属性?

谢谢, 罗伊

2 个答案:

答案 0 :(得分:7)

您每次致电GenEnumerator都会创建GetEnumerator的新实例,这就是您Currentnull的原因。而是将其存储在一个字段中并使用它。

var e = g.GetEnumerator();
if(e.MoveNext())
{
    var current = e.Current;
}

答案 1 :(得分:6)

这是因为为了让Current变为非空,您需要在同一个对象上调用MoveNext()

您当前的代码在临时对象上调用MoveNext()。这是你打电话时发生的事情

g.GetEnumerator().MoveNext()`;
Console.WriteLine(g.GetEnumerator().Current);
  • 致电GetEnumerator()会返回一个对象x
  • 正在执行电话x.MoveNext()
  • x符合垃圾回收条件,因为它不会从您程序中的任何变量引用。
  • 当您致电g.GetEnumerator().Current时,会返回一个新对象y
  • 致电y.Current,返回null,因为对象MoveNext上没有调用y

但是,当您添加变量a时,您会在同一个对象上调用MoveNextCurrent,从而解决问题:

  • 致电GetEnumerator()会返回一个对象x,该对象已分配给变量a
  • 正在执行电话a.MoveNext()
  • 正在执行电话a.Current