在C#中调试foreach循环:这是什么迭代?

时间:2010-07-20 18:21:17

标签: c# .net visual-studio debugging foreach

除了设置调试变量并在每次启动foreach时递增它,当你连接Visual Studio调试器时,有没有办法告诉这是循环中的第X个时间?

我想这将是Visual Studio的一个功能,如果有的话,不会添加到已编译的代码中。

11 个答案:

答案 0 :(得分:23)

在循环内设置断点,然后右键单击断点以设置条件。您也可以在调试时右键单击以查看命中计数,并根据需要重置它。您可以设置一个布尔表达式,当断点点击有条件地中断(或者只是传递)时,它会被计算。

答案 1 :(得分:13)

扩大Garo Yeriazarian的答案......

快速而肮脏的方式,无需重新编译。示例代码:

    var ints = new[] {5, 6, 0, 1};

    foreach (var i in ints)
    {
        Debug.WriteLine(100 / i);
    }

在循环之前添加一个断点,在其中添加一个断点。当第一个被击中并且您想要开始计数时,设置命中计数条件:

two breakpoints

设置一些大的命中计数条件并重置计数器并继续。然后,当异常或任何火灾时,您可以再次检查“当前命中数”。

Hit count dialog

答案 2 :(得分:7)

以前的Stack Overflow问题似乎是您正在寻找的问题: get-index-of-current-foreach-iteration

从该链接引用的答案:

  

Foreach用于迭代实现IEnumerable的集合。   它通过在集合上调用GetEnumerator来实现这一点   返回一个枚举器。

     

此枚举器具有方法和属性:

     
      
  • 的MoveNext()
  •   
  • 电流
  •   
     

Current返回Enumerator当前所在的对象MoveNext   更新当前的下一个对象。

     

显然,索引的概念对于概念来说是陌生的   枚举,不能做。

     

因此,大多数集合都可以使用   indexer和for循环结构。

     

我非常喜欢在这种情况下使用for循环   使用局部变量跟踪索引。

答案 3 :(得分:5)

可能是你可以使用断点命中计数。不完全是你想要的,但可能会有帮助。

在这种情况下,您还有任何严重的理由不想使用for循环。

答案 4 :(得分:4)

2017年2月更新,六年后更新 - 下面提到的扩展程序现在称为OzCode。该功能现在称为Foresee,但仅在VS2013中受支持。

我也觉得这可能是一个非常有用的功能,所以我创建它作为我为Visual Studio调试体验BugAid做的商业扩展的一部分。

扩展程序显示您在foreach循环中的确切迭代次数: Foreach Buttons

当您单击“迭代x of y”按钮时,您将看到一个新窗口,显示完整的项目列表,突出显示您在循环中的当前位置(仅在评估集合中时显示此列表调试器不会引起任何副作用。)

打开Foreach Visualization窗口后,您甚至可以右键单击任何即将出现的项目,然后选择“跳至项目”,直到您点击该项目为止(这可以避免您手动设置和搞乱)命中计数断点):

Using Skip To Iteratioon

答案 5 :(得分:3)

让我们说你的代码是

foreach (String line in lines){
    Console.WriteLine(line);//breakpoint here
}

foreach循环中放置一个断点,启动"立即窗口"并执行以下代码Array.IndexOf(lines, line);

答案 6 :(得分:2)

您是否尝试在调试中使用断言?调试器将在代码中的确切位置启动:
例如: System.Diagnostics.Debug.Assert(myValue> = 0)

答案 7 :(得分:2)

您还可以使用Visual Studio的立即窗口,它允许您在调试时针对作用域中的任何变量编写C#表达式。使用List.IndexOf()方法,如下所示:

querying the foreach iteration index in the Immediate Window

答案 8 :(得分:1)

Visual Studio 2017 中的点击次数:

  1. foreach 循环内的任意位置设置断点。
  2. 右键单击您的断点,然后单击“条件...”。

Conditions

  1. 选中“条件”框,将下拉菜单切换到“命中数”并编辑您的命中数设置。

Hit Count

  1. 暂停时,将鼠标悬停在断点上以查看您的设置和到目前为止达到的命中计数。

Hover

  1. 不要忘记,当您在同一会话中第二次进入循环时,您的点击次数不会自动重置为零。 ;-) 但是您可以手动重置它:

Reset

答案 9 :(得分:0)

如果您正在迭代的任何内容支持IndexOf()方法,则不必设置调试变量。

就像这个例子一样:

foreach (var i in myList)
{
    reportprogress(myList, i);

    //Do stuff
}

private void reportprogress<T>(List<T> l, T i)
{
    progressBar1.Value = ((l.IndexOf(i)) * 100) / l.Count;
    Application.DoEvents();
}

答案 10 :(得分:0)

这是我的操作方式[在VS 2017中]:

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