The compiler analyzes
the iterator block and creates a class that is similar to the longhand
implementation we wrote earlier, keeping all the necessary state as instance variables.
Let??™s think about what this state machine has to do in order to implement the iterator:
?– It has to have some initial state.
?– Whenever MoveNext is called, it has to execute code from the GetEnumerator
method until we??™re ready to provide the next value (in other words, until we hit
a yield return statement).
1 Or properties, as we??™ll see later on. You can??™t use an iterator block in an anonymous method, though.
Compiler
does all
the work!
167 C# 2: simple iterators with yield statements
?– When the Current property is used, it has to return the last value we yielded.
?– It has to know when we??™ve finished yielding values so that MoveNext can return
false.
The second point in this list is the tricky one, because it always needs to ???restart??? the
code from the point it had previously reached. Keeping track of the local variables (as
they appear in the method) isn??™t too hard??”they??™re just represented by instance variables
in the state machine. The restarting aspect is trickier, but the good news is that
unless you??™re writing a C# compiler yourself, you needn??™t care about how it??™s achieved:
the result from a black box point of view is that it just works.
Pages:
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337