在调试时,如何在枚举中的任意位置启动foreach循环?

时间:2014-08-20 05:25:40

标签: c# .net debugging foreach

我正在调试我的程序。我可以在调试模式下为foreach循环设置起始对象吗?例如,我希望foreach循环从我的集合的第5个元素开始。

5 个答案:

答案 0 :(得分:5)

不,你不能。 Foreach循环使用IEnumerable<T>,其中T是对象的类型。因此,与for循环不同,您无法为迭代设置初始索引或起始索引。所以你总是从第0个位置对象开始。

其他选项是使用linq,如下所示。

//Add using System.Linq  statement at top.

int[] numbers = new int[] { 1,2,3,4,5,6,7,8};

foreach(var num in numbers.Skip(5))
{
     Console.WriteLine(num);
}

答案 1 :(得分:1)

考虑到你在谈论调试我假设你要做的就是从第5个元素开始等等。如果是这种情况,那么你可以使用一个断点来指定一个命中数,它将在第n个中断等等。

请参阅MSDN here

答案 2 :(得分:1)

设置起始对象的一种简单方法是覆盖您在循环中枚举的变量。

为了说明,请考虑以下foreach循环。

IEnumerable<int> numbers = Enumerable.Range(1, 100);
foreach (int n in numbers)
{
    Console.WriteLine(n);
}
  1. 在循环初始值设定项中的numbers语句中设置断点,或者步进循环但不运行numbers语句。
  2. 使用即时窗口覆盖numbers

    的值
    numbers = numbers.Skip(5);  // or Enumerable.Skip(numbers, 5)
    
  3. 继续调试;循环从第六个元素开始。

  4. 如果您的循环使用内联计算枚举,如下所示,那么您运气不好。请考虑改为使用hit-count breakpoint

    foreach (int n in Enumerable.Range(1, 100))  // no way to change enumeration.
    {
        Console.WriteLine(n);
    }
    

    注意:运行numbers语句后,调试器将缓存您的枚举,以便它不再被更改并影响循环。您可以在逐步完成循环结构时观察到这一点。

答案 3 :(得分:0)

@ Shaggy的回答可能是最简单的,但很高兴知道旧式for循环是最快的,并且可以让你跳过0索引。

for(int x = 4; x < numbers.Length; x++)
{
    // Do anything with numbers[x]
}

即使我不推荐它(这是非常糟糕的代码),你可以在调试时使这个循环表现不同,如你所知:

#if DEBUG
for(int x = 4; x < numbers.Length; x++)
#else
for(int x = 0; x < numbers.Length; x++)    
#endif
{
    // Do anything with numbers[x]
}

答案 4 :(得分:0)

foreach不一定对甚至具有已定义顺序的集合进行操作。考虑Dictionary<T>ConcurrentBag<T>。 所以,不,这在一般情况下是不可能的,特别是没有代码更改(这可能会改变你试图调试的问题)。