FrankTheBoss
FrankTheBoss

Reputation: 193

Will this foreach loop call Split() each iteration in C#?

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?

Upvotes: 19

Views: 5896

Answers (6)

CodesInChaos
CodesInChaos

Reputation: 108840

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.

Upvotes: 5

Jon Hanna
Jon Hanna

Reputation: 113342

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.

Upvotes: 3

Rik
Rik

Reputation: 29243

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

Upvotes: 0

Kamyar
Kamyar

Reputation: 18797

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

Upvotes: 4

Niels van der Rest
Niels van der Rest

Reputation: 32194

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

Upvotes: 1

Ahmad Mageed
Ahmad Mageed

Reputation: 96537

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

Upvotes: 27

Related Questions