2010-05-14 81 views

回答

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. 
} 
7

收益率用于迭代器。

它可以让你处理小燕子的列表,这对于大列表来说很不错。

关于Yield的神奇之处在于它记住了您在调用之间所处的位置。

如果您没有迭代,则不需要Yield。

21

当您返回一个枚举值时使用yield,并且您没有所有结果。

实际上,我想在遍历大块信息(数据库,平面文件等)时使用yield,而且我不想先将所有内容加载到内存中。良率是遍历块的好方法,不需要一次加载所有内容。

1

收益率返回将继续该方法。例如,您想循环访问数组或列表,并在调用者处理时返回每个元素。所以你会使用收益率回报。如果你想回到一切,然后做了,你不需要做

1

在此解释:

C# Language Reference
yield (C# Reference)

称为将返回的每一个值,使他们能够被调用者列举的方法。

这意味着当您希望迭代返回每个可能的结果时,您将需要使用产量

6

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; 
     } 
    } 
    } 
} 

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

相关问题