2014-01-08 49 views
4

我做了以下工作为什么我无法获得当前值当我实现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类型变量?

感谢, 罗伊

+1

'GetEnumerator()'总是返回一个* new *枚举器。 *多个*统计员可以同时使用。他们并不都是一个职位。 –

回答

4

这是因为,为了使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()收益进行呼叫a.MoveNext()对象x,分配给变量a
  • 呼叫a.Current通过调用GetEnumerator进行
5

你正在创建GenEnumerator每次的新实例,这就是为什么你Currentnull。而是将其存储在一个字段中并使用它。

var e = g.GetEnumerator(); 
if(e.MoveNext()) 
{ 
    var current = e.Current; 
} 
相关问题