[...]
The question I have about the Power example is:
while (counter++ < exponent)
{
result = result * number;
yield return result;
}
indicates that block likely will execute multiple times. The question
is, where does the result go?
It's returned by IEnumerator.Current, where the IEnumerator is "returned"
(sort of) by the method in question, indirectly through the IEnumerable in
that particular example.
Note that result is declared as an
int. Is it converting the int result to IEnumerable and pad the
result to this IEnumberabilized result? This is where I don't
understand. I hope that I have made my question clear. Thank you.
To answer your direct question: no, the int is not converted to
IEnumerable.
It is a little confusing, because the compiler is hiding so much from
you. But a method that contains a "yield" statement is treated
differently from normal methods. The compiler essentially creates a
hidden class that implements the enumeration described by the method, via
the IEnumerable interface in this example.
This hidden class manages the current state. When you call the method,
all that's returned is a reference to the IEnumerable (or whatever type
was declared for the iterator) that the compiler created. Something using
IEnumerable (for example, a "foreach" loop) calls GetEnumerator() to get
the IEnumerator interface implemented by the hidden class. The compiler
has built the hidden class so that when you call IEnumerator.MoveNext(),
it executes the code in the method that you wrote until it hits the
"yield" statement. At that point, the return value is stored and the
MoveNext() implementation returns. Calling IEnumerator.Current retrieves
the stored value.
For the non-generic IEnumerable, the IEnumerator returned is of course a
non-generic implementation and so Current always returns an Object. When
the "yield" statement returns an int, this is boxed automatically. It's
then unboxed by whatever code is actually using the
IEnumerable/IEnumerator.
If you implement the generic IEnumerable<T> interface, then the value
returned by IEnumerator<T>.Current will be the same type as that returned
by the "yield" statement, without any boxing.
But in neither case does the return value associated with the "yield"
statement have anything directly to do with the declared return type of
the method. An iterator method must return IEnumerable, IEnumerator, or
the generic versions of those interfaces. The type of the "yield return"
statement determines the type of the data returned by the Current property
of the relevant enumerator interface. The _presence_ of a "yield"
statement requires that enumerable/enumerator return value, and the type
actually returned by the "yield" statement determines what Current returns
(boxed, if necessary).
For more information, if you haven't already you may want to read the
description of C# iterators:
http://msdn.microsoft.com/en-us/library/dscyy5s0.aspx(there's a link to
that document from the doc page for "yield" that you mentioned)
Pete