The State Machine here is one that is automatically generated by the C# compiler. The C# compiler internally converts lots of advanced features (like closures, the yield keyword, and async) into simplified C# before continuing. Things like 'AsyncStateMachineAttribute' is one bit of evidence that something like this has occured. You might also be familiar with classes called, e.g., DisplayClass923084923'1, which are the classes C# generates to implement closures.
When you use 'yield', say, the C# compiler first produces a version of the code which doesn't use 'yield' but instead uses a state machine implementation. In principle, from this;
yield "A";
yield "B";
to
int _state = 0;
if (_state == 0) { state = 1; return "A"; }
if (_state == 1) { state = 2; return "B"; }
This means the C# compiler, later on, doesn't have to deal with 'yield' as such -- it's been reduced to integers and return statements. I think this is where the IteratorStateMachineAttribute
is added -- to the simplified, ints-and-returns version of the class.
(I think Async works the same way, producing a simplified state machine as its simplification step, which is how you came to it in the documentation.)
However, ever since the earliest version of C#, you've had the foreach
keyword, which works on any object that has a GetEnumerator
method, and that enumerator has methods like MoveNext
and Result
.
So -- an iterator method might be produced in different ways. IteratorStateMachineAttribute
is what's supplied by the compiler in some cases, but you shouldn't rely on it being there.