Will this foreach loop call Split() each iteration in C#? – Education Career Blog

If I have a for loop like the following:

foreach(string email in installerEmails.Split(','))
{
    Console.WriteLine(email);
}

Will the Split() call be made on each iteration of the loop? Do I need to store it in a temp array before iterating through it?

,

No. It will iterate on the result of that call, i.e., the return type of Split which is a string array: string.

,

The result of Split is evaluated once, then GetEnumerator() is called on it. This returns an IEnumerator on which the MoveNext method and Current property is called in each iteration.

It’s basically equivalent to:

string enumerable=installerEmails.Split(',');
IEnumerator<string> enumerator=enumerable.GetEnumerator();
while(enumerator.MoveNext())
{
    string email=(string)enumerator.Current;
    Console.WriteLine(email);
}

One ugly detail is the explicit cast to the type you give in the for loop the compiler generates. This was useful in C# 1.0 where IEnumerator wasn’t generic.

I forgot that the Enumerator gets disposed. See Jon Hanna’s answer for the code which includes dispose.

,

No. Just debug your code. you’ll see the Split() method is only called once.

,

No. The object returned by Split (which happens to be an array, but the same applies to other enumerable objects) is what defines the loop after all. If it has zero or a million items, it is it that is defining the zero or million iterations, which it couldn’t do if it kept being called.

For a bit more detail, the code produced becomes equivalent to:

string temp = installerEmails.Split(',');
var enumerator = temp.GetEnumerator();
try
{
  while(enumerator.MoveNext())
  {
    string email = (string)enumerator.Current;
    Console.WriteLine(email);
  }
}
finally
{
  if(enumerator is IDisposable)
    ((IDisposable)enumerator).Dispose()
}

As you can see, .Split() is called only once.

,

The Split will be called once, which results in an array. The foreach then uses a single enumerator to iterate over the array.

,

No. .Split() returns an IEnumerable, and that will be used to iterate over.

Leave a Comment