yield关键字

yield关键字

yield return 语句返回集合的一个元素,并移动到下一个元素上. yield break可停止迭代.

using System;
using System.Collection;
namespace Wrox.ProCSharp.Arrays
{
  public class HelloCollection
  {
    public IEnumerator GetEnumerator()
    {
      yield return "Hello";
      yield return "World";
    }
  }
}

包含yield语句的方法或属性也称为迭代块.迭代块必须声明为返回IEnumerator或IEnumerable接口.这个块可以包含多个yield return 语句或yield break语句,但不能包含return 语句

使用迭代块,编译器会生成一个yield类型,其中包含一个状态机,yield类型执行IEnumerator和IDisposable接口的属性和方法.GetEnumerator()方法实例化并返回一个新的yield类型.在yield类型中,变量state定义了迭代的当前位置,每次调用 MoveNext()时,当前位置都会改变.MoveNext()封装了迭代块的代码,设置了current变量的值,使Current属性根据位置返回一个对象.如下代码
public class HelloCollection
{
  public IEnumerator GetEnumerator()
  {
    Enumerator enumerator = new Enumerator();
    return enumerator;
  }
  
  public clss Enumerator : IEnumerator, IDisposable
  {
    private int state;
    private object current;
    public Enumerator(int state)
    {
      this.state = state;
    }
    bool System.Collections.IEnumerator.MoveNext()
    {
      switch(state)
      {
        case 0:
          current = "Hello";
          state = 1;
          return true;
        case 1:
          current = "World";
          state = 2;
          return true;
        case 2:
          break;
      }
      return false;
    }
   
    void System.Collections.IEnumerator.Reset()
    {
      throw new NotSupportedException();
    }

    object System.Collections.IEnumerator.Current
    {
      get
      {
        return current;
      }
    }

    void IDisposable.Dispose()
    {
    }
  }
}

现在使用yield return 语句,很容易实现允许以不同方式迭代集合的类.类MusicTitles可以用默认方式通过GetEnumerator()方法迭代标题,用Reverse()方法逆序迭代标题,用Subset()方法搜索子集:
public class MusicTitles
{
  string[] names = {"aa","bb","cc"};
  
  public IEnumerator GetEnumerator()
  {
    for(int i = 0; i < 4; i++)
    {
      yield return names;
    }
  }

  public IEnumerable Reverse()
  {
    for(int i = 3; i >= 0; i --)
    {
      yield return names;
    }
  }

  public IEnumerable Subset(int index, int length)
  {
    for(int i = index; i < index + length; i++)
    {
      yield return names;
    }
  }
}

yield语句还可以完成更复杂的任务,例如从yield return 中返回枚举器.
原文地址:https://www.cnblogs.com/cpcpc/p/2123128.html