这个foreach循环会在C#中每次迭代调用Split()吗?

时间:2010-10-14 14:41:31

标签: c#

如果我有以下的for循环:

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

是否会在循环的每次迭代中调用Split()?在迭代之前我是否需要将它存储在临时数组中?

6 个答案:

答案 0 :(得分:26)

没有。它将迭代该调用的结果,即Split的返回类型,它是一个字符串数组:string[]

答案 1 :(得分:5)

对Split的结果进行一次计算,然后调用GetEnumerator()。这将返回一个IEnumerator,在每次迭代中调用MoveNext方法和Current属性。

它基本上相当于:

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

一个丑陋的细节是对编译器生成的for循环中给出的类型的显式强制转换。这在C#1.0中很有用,其中IEnumerator不是通用的。

我忘记了调查员被处理掉了。请参阅Jon Hanna对包含处置的代码的回答。

答案 2 :(得分:4)

没有。只需调试您的代码。你会看到Split()方法只被调用一次。

答案 3 :(得分:3)

没有。 Split返回的对象(恰好是一个数组,但同样适用于其他可枚举对象)毕竟定义了循环。如果它有零个或一百万个项目,那就是定义零或百万次迭代,如果它继续被调用就无法做到。

有关详细信息,生成的代码等同于:

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()
}

如您所见,.Split()只被调用一次。

答案 4 :(得分:1)

Split将被调用一次,从而产生一个数组。然后foreach使用单个枚举器迭代数组。

答案 5 :(得分:0)

没有。 .Split()返回一个IEnumerable,它将用于迭代。