什么时候使用Yield?

lea*_*ing 22 c#

我什么时候应该使用退货收益率,何时才能使用退货?

bry*_*ker 22

返回可枚举时使用yield,并且此时没有所有结果.

实际上,当我想迭代大量信息(数据库,平面文件等)时,我已经使用了yield,而且我不想先将所有内容加载到内存中.Yield是一种很好的方法,可以在不加载所有内容的情况下迭代块.


Bri*_*eon 8

yield关键字是非常强大的.它基本上允许您快速返回IEnumerableIEnumerator对象而无需显式编码.

考虑一种情况,您希望返回两个IEnumerable对象的交集.以下是使用yield关键字执行此操作的方法.

public static class Program
{
  public static void Main()
  {
    IEnumerable<object> lhs = new List<int> { 1, 2, 3, 4, 5 };
    IEnumerable<object> rhs = new List<int> { 3, 4, 5, 6, 7 };
    foreach (object item in IntersectExample.Intersect(lhs, rhs))
    {
      Console.WriteLine(item);
      break;
    }
  }
}

public static class IntersectExample
{
  public static IEnumerable<object> Intersect(IEnumerable<object> lhs, IEnumerable<object> rhs)
  {
    var hashset = new HashSet<object>();
    foreach (object item in lhs)
    {
      if (!hashset.Contains(item))
      {
        hashset.Add(item);
      }
    }
    foreach (object item in rhs)
    {
      if (hashset.Contains(item))
      {
        yield return item;
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在你完全意识到发生了什么之前,很难理解这一点.通常,当您将两个集相交时,您将完成整个操作,然后将结果返回给调用者.这意味着操作的运行时复杂性,无论您以后对结果执行什么操作O(m + n),其中mn将是相交的集合的大小.但是,在我的例子中,我只是想从结果中挑选第一个项目.使用IEnumerableyield关键字创建的内容,可以非常轻松地延迟部分处理,直到实际需要为止.我的例子在O(m).另一种方法是IEnumerable手动编码并维护状态.关键字的强大之yield处在于它为您创建了状态机.


Ed *_*ess 7

收益率是针对迭代器的.

它允许您处理小燕子中的列表,这对大型列表很有用.

关于Yield的神奇之处在于它会记住你在调用之间的位置.

如果你没有迭代,你不需要收益率.


Mar*_*tos 6

yield构造用于创建迭代器,该迭代器可以连续生成多个值:

IEnumerable<int> three_numbers() {
    yield return 1;
    yield return 2;
    yield return 3;
}
...
foreach (var i in three_numbers()) {
    // i becomes 1, 2 and 3, in turn.
}
Run Code Online (Sandbox Code Playgroud)