【发布时间】:2010-10-14 14:41:31
【问题描述】:
如果我有如下的 for 循环:
foreach(string email in installerEmails.Split(','))
{
Console.WriteLine(email);
}
是否会在循环的每次迭代中调用 Split()?在迭代之前是否需要将其存储在临时数组中?
【问题讨论】:
标签: c#
如果我有如下的 for 循环:
foreach(string email in installerEmails.Split(','))
{
Console.WriteLine(email);
}
是否会在循环的每次迭代中调用 Split()?在迭代之前是否需要将其存储在临时数组中?
【问题讨论】:
标签: c#
没有。它将迭代该调用的结果,即Split 的返回类型,它是一个字符串数组:string[]。
【讨论】:
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 循环中给出的类型。这在 IEnumerator 不是通用的 C# 1.0 中很有用。
我忘记了 Enumerator 被处理掉了。请参阅 Jon Hanna 对包含 dispose 的代码的回答。
【讨论】:
没有。只需调试您的代码。你会看到 Split() 方法只被调用一次。
【讨论】:
没有。 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() 只被调用一次。
【讨论】:
Split 将被调用一次,从而生成一个数组。然后foreach 使用单个枚举器遍历数组。
【讨论】:
while 的目的:) 我已将其从我的答案中删除,谢谢。
没有。 .Split() 返回一个 IEnumerable,它将用于迭代。
【讨论】: