调试器能告诉我foreach循环的计数/状态吗

本文关键字:状态 告诉我 foreach 循环 调试器 | 更新日期: 2023-09-27 17:58:53

假设我有以下代码:

List<SomeObject> someObjects = ReturnListWithThousandsOfObjects();
foreach(SomeObject someobject in someObjects)
{
   DoSomething.With(someObject);
}

还假设运行一分钟后,我在DoSomething.With(someObject);上设置了一个断点。

调试器对我来说很好。但现在我想知道我在列表的迭代中处于什么位置(假设列表是无序的/没有键)。

调试器有没有办法说"foreach已经运行了2321次迭代中的532次"?

调试器能告诉我foreach循环的计数/状态吗

作为一个调试工具,难道没有indexof方法吗?

quickwatch-someObjects.indexOf(someObject);

添加-抱歉,如果有点简短。

正如Guffa所指出的,如果值是唯一的,或者默认的相等比较器EqualityComparer函数使用唯一的值(例如自定义的GetHashCode/Equals重载),这将最有效。

    public class ATest
    {
        public int number { get; set; }
        public int boo { get; set; }
        public ATest()
        {
        }
    }
    protected void Go()
    {
        List<ATest> list = new List<ATest>();
        foreach(var i in Enumerable.Range(0,30)) {
            foreach(var j in Enumerable.Range(0,100)) {
                list.Add(new ATest() { number = i, boo = j });                  
            }
        }
        var o =0; //only for proving concept.
        foreach (ATest aTest in list)
        {               
            DoSomthing(aTest);
            //proof that this does work in this example.
            o++;
            System.Diagnostics.Debug.Assert(o == list.IndexOf(aTest));
        }
    }

这是针对Visual Studio的,但其他IDE应该有类似的功能:

当您设置断点时,您可以右键单击它并转到"命中计数"。您可以在那里设置一些参数("大于或等于"0将使其像常规断点一样工作——"总是中断"也是如此)。有趣的部分是命中计数字段(可以重置)。

这可以解决"迭代次数"部分。对于总数,我担心你必须自己找到它,假设你使用的收藏有这样一个现成的数字。

你也可以设置断点,在大量点击后触发,比如几千次/数百万次(我不知道它们的极限是多少)。然后,当"真正的"断点触发时,也就是你想知道原始断点被击中了多少次的断点,你可以检查它,并在需要时重置它。

在这种情况下,如果你真的想知道计数是多少,你不会使用for循环吗?

List<SomeObject> someObjects = ReturnListWithThousandsOfObjects();

for(int someObj= 1; someObj <= someObjects.Count; someObj++)
{
   Console.WriteLine(string.Format("{0} of {1} iterations", someObj, someObjects.Count));
   DoSomething.With(someObject[someObj]);
}

foreachfor循环之间的性能不会有真正的差异——因此,对于您想要实现的情况,for循环将是一个更好的选择。

除非手动在变量中保持计数,否则无法轻松确定。当循环在集合中迭代时,它只使用枚举器来获取集合中的下一个元素,告诉它在退出时不再有元素。

要手动保持计数,您只需执行以下操作:

int count = 0;
List<SomeObject> someObjects = ReturnListWithThousandsOfObjects();
foreach(SomeObject someobject in someObjects)
{
     count++;
     DoSomething.With(someObject);
}

现在,在任何时候,您都可以暂停执行,并查看您在上的迭代

在List和List上创建一个扩展方法,该方法接受Action fold、Action sideFold,让您积累副作用,如检查调试器的存在和中断累积状态。

可以。以下是[在VS 2017]:

  1. 在foreach循环内设置断点
  2. 右键单击断点并选择"操作"
  3. 在文本框中,输入以下内容:$FUNCTION {list.Items.IndexOf(item)},其中"list"是列表的名称,"item"是当前项目
  4. 继续运行代码并观察输出窗口