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

时间:2011-06-09 21:16:59

标签: c# debugging foreach

假设我有以下代码:

List<SomeObject> someObjects = ReturnListWithThousandsOfObjects();

foreach(SomeObject someobject in someObjects)
{
   DoSomething.With(someObject);
}

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

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

调试器是否有办法说“foreach运行了2321次迭代中的532次”?

6 个答案:

答案 0 :(得分:9)

作为一个调试,没有一个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));
        }

    }

答案 1 :(得分:5)

这适用于Visual Studio,但其他IDE应该有类似的东西:

设置断点时,可以右键单击它并转到“命中计数”。您可以在那里设置一些参数(“大于或等于”0将使其像常规断点一样工作 - 因此将“始终打破”)。有趣的部分是命中计数字段(可以重置)。

这可以解决“迭代次数”部分。对于总数,我担心你将不得不自己找到它,假设你使用的收藏品有这样的数字。

您还可以将断点设置为在大量点击之后触发,比如几千/百万(我不知道它们的限制是多少)。 然后,当“真正的”断点触发时,您想要知道原点断点被击中的次数,您可以检查它并在需要时重置它。

答案 2 :(得分:2)

在这种情况下,如果你真的想知道计数是什么,你会不会使用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循环将是您想要实现的情况的更好选择。

答案 3 :(得分:1)

除非您手动记录变量,否则您将无法轻易确定。当循环在你的集合中迭代时,它只是使用枚举器来获取集合中的下一个元素,告诉它不再存在它退出的元素。

要手动保持计数:

int count = 0;
List<SomeObject> someObjects = ReturnListWithThousandsOfObjects();

foreach(SomeObject someobject in someObjects)
{
     count++;
     DoSomething.With(someObject);
}

现在,您可以暂停执行并查看您正在进行的迭代

答案 4 :(得分:0)

在List和List上创建一个扩展方法,它接受一个Action fold,Action sideFold,让你累积副作用,比如检查是否存在调试器并打破累积状态。

答案 5 :(得分:-1)

是的。 [在VS 2017中]的方法如下:

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