foreach in C# recalculation

Your question is answered by section 8.8.4 of the specification, which states:


The above steps, if successful, unambiguously produce a collection type C, enumerator type E and element type T. A foreach statement of the form

foreach (V v in x) embedded-statement

is then expanded to:

{
    E e = ((C)(x)).GetEnumerator();
    try {
        V v;
        while (e.MoveNext()) {
            v = (V)(T)e.Current;
            embedded-statement
        }
    }
    finally {
        … // Dispose e
    }
}

As you can see, in the expansion the expression x is only evaluated once.


It will only calculate it once


It depends on what you mean by once. If you have a method like the following:

public static IEnumerable<int> veryComplicatedFunction()
{
    List<string> l = new List<string> { "1", "2", "3" };
    foreach (var item in l)
    {
        yield return item;
    }
}

Control would be returned to the method calling veryComplicatedFunction after each yield. So if they were sharing List l then you could have some strange results. A sure fire way to remove that kind of problem would be calling the ToArray extension on the veryComplicatedFunction.

Tags:

C#