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

时间:2022-03-12 20:44:19

Other than setting a debug variable and incrementing it every time you start the foreach, when you break in with the Visual Studio debugger connected, is there a way to tell that this is the Xth time through the loop?

除了在每次启动foreach时设置一个调试变量并对其进行递增,当您连接到Visual Studio调试器时,是否有一种方法可以告诉您这是通过循环的第xtime ?

I guess this would be a feature of Visual Studio if anything, not something that would be added to the compiled code.

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

8 个解决方案

#1


6  

Heres a previous Stack Overflow question that seems to be what your looking for: get-index-of-current-foreach-iteration

这里有一个先前的堆栈溢出问题,这似乎是您所要寻找的:当前迭代的获取索引

Answer quoted from that link:

该链接引用的回答:

Foreach is for iterating over collections that implement IEnumerable. It does this by calling GetEnumerator on the collection, which will return an Enumerator.

Foreach是用于遍历实现IEnumerable的集合。它通过调用集合上的GetEnumerator来实现这一点,该集合将返回一个枚举数。

This Enumerator has a method and a property:

此枚举器有一个方法和属性:

  • MoveNext()
  • MoveNext()
  • Current
  • 当前的

Current returns the object that Enumerator is currently on, MoveNext updates Current to the next object.

Current返回枚举器当前所在的对象,MoveNext更新下一个对象的当前状态。

Obviously, the concept of an index is foreign to the concept of enumeration, and cannot be done.

显然,索引的概念与枚举的概念并不相关,而且不能这样做。

Because of that, most collections are able to be traversed using an indexer and the for loop construct.

因此,大多数集合都可以使用索引器和for循环结构进行遍历。

I greatly prefer using a for loop in this situation compared to tracking the index with a local variable.

与使用局部变量跟踪索引相比,我更喜欢在这种情况下使用for循环。

#2


22  

Set a breakpoint inside the loop, then right click on the breakpoint to set the conditions. You can also right click to see the hit count while debugging and reset it if you want. You can set a boolean expression that is evaluated when the breakpoint hits to conditionally break (or just pass over).

在循环中设置一个断点,然后右击断点来设置条件。您还可以在调试时右键单击以查看命中数量,如果您愿意,还可以重置它。您可以设置一个布尔表达式,该表达式在断点到达有条件中断(或只是传递)时进行计算。

#3


13  

Expanding on Garo Yeriazarian's answer...

根据Garo Yeriazarian的回答…

A quick and dirty way without recompiling. Example code:

不需要重新编译的快速而肮脏的方法。示例代码:

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

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

Add one breakpoint before the loop and one inside it. When the first is hit and you want to start counting, set a Hit Count condition:

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

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

Set some large hit count condition and reset the counter and continue. Then when the exception or whatever fires, you can check the "Current hit count" again.

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

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

#4


5  

May be you can use breakpoint hit count. Not exactly what you want, but may be helpful.

也许你可以使用断点计数。不是你想要的,但可能会有帮助。

Also is there any serious reason why you don't want to use for loop in this case.

同样,在这种情况下,您不希望使用for循环有什么严重的原因吗?

#5


4  

Update Feb 2017, six years later - the extension mentioned below is now called OzCode. The feature is now called Foresee, but is only supported in VS2013.

更新于2017年2月,6年之后——下面提到的扩展现在被称为OzCode。该特性现在被称为预见,但仅在VS2013中得到支持。

I also felt that this could be a very useful feature, so I created it as part of a commercial extension I made for the Visual Studio debugging experience called BugAid.

我还觉得这可能是一个非常有用的特性,所以我将它作为我为Visual Studio调试体验(称为BugAid)开发的商业扩展的一部分。

The extension shows you exactly which iteration you are whenever you are inside a foreach loop: 在c#中调试foreach循环:这是什么迭代?

当你在一个foreach循环中时,这个扩展会精确地告诉你你是哪个迭代:

When you click the "Iteration x of y" button, you'll see a new window, showing the complete list of items, with the your current location in the loop highlighted (this list is only shown if evaluating the collection in the debugger does not cause any side effects).

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

Once you open ths Foreach Visualization window, you can even right click any of the upcoming items and choose "Skip to Item", to run forward until you hit that item (this can save you from manually setting-up and messing with hit-count breakpoint):

打开每个可视化窗口之后,你甚至可以右键单击任何即将出现的项目,选择“跳转到项目”,向前运行,直到你点击该项目(这可以避免手动设置和打乱命中计数断点):

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

#6


2  

Have you tried using assertion in debugging? The debugger will be launched at that exact point in your code:
For example: System.Diagnostics.Debug.Assert (myValue >=0)

你试过在调试中使用断言吗?调试器将在您的代码的这个特定位置启动:例如:System.Diagnostics.Debug。断言(myValue > = 0)

#7


0  

If whatever you are iterating supports the IndexOf() method, you don't have to set a debug variable.

如果迭代支持IndexOf()方法,则不需要设置调试变量。

Like in this example:

在这个例子中:

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();
}

#8


0  

Let's say your code is

假设你的代码是

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

Put a breakpoint inside foreach loop, launch "Immediate window" and execute following code Array.IndexOf(lines, line);

在foreach循环中放置一个断点,启动“立即窗口”并执行以下代码数组。IndexOf(线、线);

#1


6  

Heres a previous Stack Overflow question that seems to be what your looking for: get-index-of-current-foreach-iteration

这里有一个先前的堆栈溢出问题,这似乎是您所要寻找的:当前迭代的获取索引

Answer quoted from that link:

该链接引用的回答:

Foreach is for iterating over collections that implement IEnumerable. It does this by calling GetEnumerator on the collection, which will return an Enumerator.

Foreach是用于遍历实现IEnumerable的集合。它通过调用集合上的GetEnumerator来实现这一点,该集合将返回一个枚举数。

This Enumerator has a method and a property:

此枚举器有一个方法和属性:

  • MoveNext()
  • MoveNext()
  • Current
  • 当前的

Current returns the object that Enumerator is currently on, MoveNext updates Current to the next object.

Current返回枚举器当前所在的对象,MoveNext更新下一个对象的当前状态。

Obviously, the concept of an index is foreign to the concept of enumeration, and cannot be done.

显然,索引的概念与枚举的概念并不相关,而且不能这样做。

Because of that, most collections are able to be traversed using an indexer and the for loop construct.

因此,大多数集合都可以使用索引器和for循环结构进行遍历。

I greatly prefer using a for loop in this situation compared to tracking the index with a local variable.

与使用局部变量跟踪索引相比,我更喜欢在这种情况下使用for循环。

#2


22  

Set a breakpoint inside the loop, then right click on the breakpoint to set the conditions. You can also right click to see the hit count while debugging and reset it if you want. You can set a boolean expression that is evaluated when the breakpoint hits to conditionally break (or just pass over).

在循环中设置一个断点,然后右击断点来设置条件。您还可以在调试时右键单击以查看命中数量,如果您愿意,还可以重置它。您可以设置一个布尔表达式,该表达式在断点到达有条件中断(或只是传递)时进行计算。

#3


13  

Expanding on Garo Yeriazarian's answer...

根据Garo Yeriazarian的回答…

A quick and dirty way without recompiling. Example code:

不需要重新编译的快速而肮脏的方法。示例代码:

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

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

Add one breakpoint before the loop and one inside it. When the first is hit and you want to start counting, set a Hit Count condition:

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

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

Set some large hit count condition and reset the counter and continue. Then when the exception or whatever fires, you can check the "Current hit count" again.

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

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

#4


5  

May be you can use breakpoint hit count. Not exactly what you want, but may be helpful.

也许你可以使用断点计数。不是你想要的,但可能会有帮助。

Also is there any serious reason why you don't want to use for loop in this case.

同样,在这种情况下,您不希望使用for循环有什么严重的原因吗?

#5


4  

Update Feb 2017, six years later - the extension mentioned below is now called OzCode. The feature is now called Foresee, but is only supported in VS2013.

更新于2017年2月,6年之后——下面提到的扩展现在被称为OzCode。该特性现在被称为预见,但仅在VS2013中得到支持。

I also felt that this could be a very useful feature, so I created it as part of a commercial extension I made for the Visual Studio debugging experience called BugAid.

我还觉得这可能是一个非常有用的特性,所以我将它作为我为Visual Studio调试体验(称为BugAid)开发的商业扩展的一部分。

The extension shows you exactly which iteration you are whenever you are inside a foreach loop: 在c#中调试foreach循环:这是什么迭代?

当你在一个foreach循环中时,这个扩展会精确地告诉你你是哪个迭代:

When you click the "Iteration x of y" button, you'll see a new window, showing the complete list of items, with the your current location in the loop highlighted (this list is only shown if evaluating the collection in the debugger does not cause any side effects).

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

Once you open ths Foreach Visualization window, you can even right click any of the upcoming items and choose "Skip to Item", to run forward until you hit that item (this can save you from manually setting-up and messing with hit-count breakpoint):

打开每个可视化窗口之后,你甚至可以右键单击任何即将出现的项目,选择“跳转到项目”,向前运行,直到你点击该项目(这可以避免手动设置和打乱命中计数断点):

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

#6


2  

Have you tried using assertion in debugging? The debugger will be launched at that exact point in your code:
For example: System.Diagnostics.Debug.Assert (myValue >=0)

你试过在调试中使用断言吗?调试器将在您的代码的这个特定位置启动:例如:System.Diagnostics.Debug。断言(myValue > = 0)

#7


0  

If whatever you are iterating supports the IndexOf() method, you don't have to set a debug variable.

如果迭代支持IndexOf()方法,则不需要设置调试变量。

Like in this example:

在这个例子中:

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();
}

#8


0  

Let's say your code is

假设你的代码是

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

Put a breakpoint inside foreach loop, launch "Immediate window" and execute following code Array.IndexOf(lines, line);

在foreach循环中放置一个断点,启动“立即窗口”并执行以下代码数组。IndexOf(线、线);