当我有一个代码块
static void Main()
{
foreach (int i in YieldDemo.SupplyIntegers())
{
Console.WriteLine("{0} is consumed by foreach iteration", i);
}
}
class YieldDemo
{
public static IEnumerable<int> SupplyIntegers()
{
yield return 1;
yield return 2;
yield return 3;
}
}
Run Code Online (Sandbox Code Playgroud)
我可以将收益率收益背后的原理解释为
|1| |2| |3| are stored in contiguous memory block.Pointer of "IEnumerator" Moves to |1|澄清:
(1)通常我们将在函数内部允许一个有效的return语句.当多个yield return,yield return,...语句出现时C#如何处理?
(2)一旦遇到回报,就无法再次控制回到SupplyIntegers(),如果允许则不会再从1开始收益?我的意思是收益率1?
Mar*_*ell 33
不 - 远非如此; 我会为你写一个长手版......它太蹩脚了!
请注意,如果您了解它foreach实际上是有帮助的:
using(var iterator = YieldDemo.SupplyIntegers().GetEnumerator()) {
int i;
while(iterator.MoveNext()) {
i = iterator.Current;
Console.WriteLine("{0} is consumed by foreach iteration", i);
}
}
Run Code Online (Sandbox Code Playgroud)
using System;
using System.Collections;
using System.Collections.Generic;
static class Program
{
static void Main()
{
foreach (int i in YieldDemo.SupplyIntegers())
{
Console.WriteLine("{0} is consumed by foreach iteration", i);
}
}
}
class YieldDemo
{
public static IEnumerable<int> SupplyIntegers()
{
return new YieldEnumerable();
}
class YieldEnumerable : IEnumerable<int>
{
public IEnumerator<int> GetEnumerator()
{
return new YieldIterator();
}
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}
class YieldIterator : IEnumerator<int>
{
private int state = 0;
private int value;
public int Current { get { return value; } }
object IEnumerator.Current { get { return Current; } }
void IEnumerator.Reset() { throw new NotSupportedException(); }
void IDisposable.Dispose() { }
public bool MoveNext()
{
switch (state)
{
case 0: value = 1; state = 1; return true;
case 1: value = 2; state = 2; return true;
case 2: value = 3; state = 3; return true;
default: return false;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它在迭代器中构建了一个状态机,状态机逐步推进MoveNext.我已经将模式与state字段一起使用,因为您可以看到这对于更复杂的迭代器是如何工作的.
重要的:
finally块(包括using),它会进入Dispose()yield return成为case(大致)的代码部分yield break成为state = -1; return false;(或类似)C#编译器执行此操作的方式非常复杂,但它使编写迭代器变得轻而易举.
| 归档时间: |
|
| 查看次数: |
4177 次 |
| 最近记录: |