gnewsgroup
Sun May 11 22:02:31 CDT 2008
On May 11, 7:51 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
> On Sun, 11 May 2008 16:10:23 -0700, gnewsgroup <gnewsgr...@gmail.com>
> wrote:
>
> > [...]
> > The question I have about the Power example is:
>
> > The while loop:
>
> > 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
Thank you Peter for the detailed explanation. I think things are
getting much clearer now. The iterator article, albeit short, is very
helpful. I will re-read your explanation and practice a little to
thoroughly understand this whole thing. Thanks again.