Question

Suppose I have the following code:

foreach(string str in someObj.GetMyStrings())
{
    // do some stuff
}

Will someObj.GetMyStrings() be called on every iteration of the loop? Would it be better to do the following instead:

List<string> myStrings = someObj.GetMyStrings();
foreach(string str in myStrings)
{
    // do some stuff
}

?

Was it helpful?

Solution

The function's only called once, to return an IEnumerator<T>; after that, the MoveNext() method and the Current property are used to iterate through the results:

foreach (Foo f in GetFoos())
{
    // Do stuff
}

is somewhat equivalent to:

using (IEnumerator<Foo> iterator = GetFoos().GetEnumerator())
{
    while (iterator.MoveNext())
    {
        Foo f = iterator.Current;
        // Do stuff
    }
}

Note that the iterator is disposed at the end - this is particularly important for disposing resources from iterator blocks, e.g.:

public IEnumerable<string> GetLines(string file)
{
    using (TextReader reader = File.OpenText(file))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            yield return line;
        }
    }
}

In the above code, you really want the file to be closed when you finish iterating, and the compiler implements IDisposable cunningly to make that work.

OTHER TIPS

No.. the function will get called once to get the IEnumerable.. and then there will be repeated call to MoveNext and Current.

GetMyStrings() retuns an object of type IEnumerable. The runtime knows how to deal with that. It calls IEnumerable.GetEnumerator() and then on that enumerator object calls MoveNext() and Current.

Just to round the question off in case you fall into a "all for's are the same"; for(int x=0;x < ProvideCeiling(); x++) does call the function each time.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top