方法在循环声明内执行

本文关键字:执行 声明 循环 方法 | 更新日期: 2023-09-27 18:01:13

我在查看我正在开发的一个网站的性能时,发现了一些我写的代码:

 foreach (WorkItem wi in p.getWorkItems(dateFrom, dateTo))
 {
     someFunction(wi);
 }

在上面的代码中,p.getWorkItems方法是否在每次执行循环时都会运行?还是执行一次,将结果对象保存在内存中,然后将指针增加到它正在使用的对象?原因是getWorkItems在幕后做了大量的工作(比较、排序、其他查询(,因此最好不要反复执行。如果是这样的话,那么我最好按照以下方式进行:

 List<WorkItem> workload = p.getWorkItems(dateFrom, dateTo);
 for (int i = 0; i < workload.Count; i++)
 {
     someFunction(workload[i]);
 }

它是用C#编写的,但我假设答案适用于大多数类似的语言。。

方法在循环声明内执行

您应该了解如何将foreach循环转换为C#代码。从C#语言规范的8.8.4开始,您的循环

foreach (WorkItem wi in p.getWorkItems(dateFrom, dateTo)) {
   someFunction(wi);
}

成为

var enumerator = p.getWorkItems(dateFrom, dateTo).GetEnumerator();
try {
    WorkItem wi;
    while(enumerator.MoveNext()) {
        wi = (WorkItem)enumerator.Current;
        someFunction(wi);
    }
}
finally {
    IDisposable disposable = enumerator as System.IDisposable;
    if (disposable != null) disposable.Dispose();
}

因此,显然p.getWorkItems只执行一次。

还是执行一次,将结果对象保存在内存中,然后将指针增加到它正在使用的对象?

是的。(*(您可以通过在getWorkItems中放入打印语句来向自己证明这一点。

(*(除非结果对象递归地调用getWorkItems

p.getWorkItems只被调用一次。结果存储在内存中,foreach循环迭代内存中的结果对象。

如果不是这样,那么每次方法都会返回新的列表,foreach将永远不会结束。

一个小型的证明应用程序:

using System;
using System.Collections.Generic;
public class Program
{
    public static void Main()
    {
        foreach(var i in GetCol()) {
            Console.WriteLine(i);
        }
    }
    private static List<int> GetCol() {
        Console.WriteLine("I have been called");
        return new List<int>(){1, 2, 3, 4};
    }
}
/* Output
I have been called
1
2
3
4 */