【问题标题】:Will this foreach loop call Split() each iteration in C#?这个 foreach 循环会在 C# 中的每次迭代中调用 Split() 吗?
【发布时间】:2010-10-14 14:41:31
【问题描述】:

如果我有如下的 for 循环:

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

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

【问题讨论】:

标签: c#


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    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 的代码的回答。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        没有。 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() 只被调用一次。

        【讨论】:

          【解决方案5】:

          Split 将被调用一次,从而生成一个数组。然后foreach 使用单个枚举器遍历数组。

          【讨论】:

          • 从什么优化?它首先定义了循环。
          • @Jon Hanna:我的错,我在一个 while 循环的上下文中思考了一秒钟。它不会在那里优化任何东西,这会破坏while 的目的:) 我已将其从我的答案中删除,谢谢。
          【解决方案6】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-10-14
            • 1970-01-01
            • 2011-03-18
            • 1970-01-01
            • 2018-09-01
            • 2019-03-26
            • 2014-05-29
            • 1970-01-01
            相关资源
            最近更新 更多