visual-studio 在 C# 中调试 foreach 循环:这是什么迭代?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3293051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Debugging a foreach loop in C#: what iteration is this?
提问by Matt
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 调试器的情况下闯入时,有没有办法告诉这是循环的第 X 次?
I guess this would be a feature of Visual Studio if anything, not something that would be added to the compiled code.
我想这将是 Visual Studio 的一个功能,而不是添加到编译代码中的功能。
采纳答案by jumpdart
Heres a previous Stack Overflow question that seems to be what your looking for: get-index-of-current-foreach-iteration
这是以前的堆栈溢出问题,这似乎是您要找的: 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.
This Enumerator has a method and a property:
- MoveNext()
- Current
Current returns the object that Enumerator is currently on, MoveNext updates Current to the next object.
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.
I greatly prefer using a for loop in this situation compared to tracking the index with a local variable.
Foreach 用于迭代实现 IEnumerable 的集合。它通过在集合上调用 GetEnumerator 来完成此操作,该集合将返回一个 Enumerator。
这个 Enumerator 有一个方法和一个属性:
- 移动下一步()
- 当前的
Current 返回 Enumerator 当前所在的对象,MoveNext 将 Current 更新为下一个对象。
显然,索引的概念与枚举的概念无关,无法做到。
因此,大多数集合都可以使用索引器和 for 循环构造进行遍历。
与使用局部变量跟踪索引相比,我更喜欢在这种情况下使用 for 循环。
回答by Garo Yeriazarian
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).
在循环内设置断点,然后在断点上单击鼠标右键以设置条件。您还可以在调试时右键单击以查看命中计数,并根据需要重置它。您可以设置一个布尔表达式,当断点命中时评估该表达式以有条件地中断(或只是跳过)。
回答by johv
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:
在循环之前添加一个断点,在循环内部添加一个。当第一个命中并且您想开始计数时,设置一个命中计数条件:


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.
设置一些大的命中计数条件并重置计数器并继续。然后,当异常或任何触发时,您可以再次检查“当前命中计数”。


回答by Jeremy Deal
回答by Incognito
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 forloop in this case.
for在这种情况下,您还有什么不想使用循环的严重原因。
回答by Omer Raviv
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 月更新,六年后- 下面提到的扩展现在称为OzCode。该功能现在称为Foresee,但仅在 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:

每当您处于 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).
当您单击“Iteration x of y”按钮时,您将看到一个新窗口,显示项目的完整列表,并突出显示您在循环中的当前位置(仅当在调试器中评估集合时才会显示此列表不会造成任何副作用)。
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):
一旦您打开 Foreach Visualization 窗口,您甚至可以右键单击任何即将出现的项目并选择“跳到项目”,向前运行直到您点击该项目(这可以避免手动设置和搞乱点击计数断点):


回答by brandonstrong
Here's how I do it [in VS 2017] :
这是我的方法 [在 VS 2017 中]:
- Set a break point inside the foreach loop
- Right click the break point and select 'Actions'
- In the text box, enter the following:
$FUNCTION {list.Items.IndexOf(item)}where 'list' is the name of your list and 'item' is the current item - Continue running the code and watch the output window
- 在 foreach 循环内设置断点
- 右键单击断点并选择“操作”
- 在文本框中,输入以下内容:
$FUNCTION {list.Items.IndexOf(item)}其中“list”是列表名称,“item”是当前项目 - 继续运行代码并观察输出窗口
回答by user961954
Let's say your code is
假设您的代码是
foreach (String line in lines){
Console.WriteLine(line);//breakpoint here
}
Put a breakpoint inside foreachloop, launch "Immediate window" and execute following code Array.IndexOf(lines, line);
在foreach循环中放置一个断点,启动“立即窗口”并执行以下代码Array.IndexOf(lines, line);
回答by user961954
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.Assert (myValue >=0)
回答by Luiscencio
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();
}

