C#: How to translate the Yield Keyword

邮差的信 提交于 2019-12-05 16:49:53

Back in the good old days, before we had the yield operator, we used to write classes which implemented IEnumerator.

class PowerEnumerator : IEnumerator<int>
{
  private int _number;
  private int _exponent;
  private int _current = 1;

  public PowerEnumerator(int number, int exponent)
  {
    _number = number;
    _exponent = exponent;
  }

  public bool MoveNext()
  {
    _current *= number;
    return _exponent-- > 0;
  }

  public int Current
  {
    get
    {
      if (_exponent < 0) throw new InvalidOperationException();
      return _current;
    }
  }
}

Or something like that. It wasn't fun, let me tell you.

First off, yield is not an operator. yield return and yield break are statements.

There are plenty of articles available on how the compiler implements iterator blocks. Start by reading the C# specification section on iterator blocks; it gives some suggestions for how an implementer of C# might want to go about it.

Next read Raymond Chen's series "The implementation of iterators in C# and its consequences"

http://www.bing.com/search?q=raymond+chen+the+implementation+of+iterators

Next, read Jon Skeet's book chapter on the subject:

http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx

If after all that you are still interested then read my series on the design factors that went into this feature:

http://blogs.msdn.com/b/ericlippert/archive/tags/iterators/

  1. Let .NET Reflector decompile it. It's a generic solution (a state machine actually), but quite complex, > 20 lines of codes if I remember correctly.
  2. Lazy. That's the point why yield can be quite efficient.
Kent Boogaart
  1. It would be a custom implementation of IEnumerable<T>, not leaning on an existing implementation such as List<T>
  2. Lazily.

More info available here.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!