C# 如何在函数的N次递归调用时中断程序?

C# 如何在函数的N次递归调用时中断程序?,c#,debugging,rider,C#,Debugging,Rider,我的程序中有一个递归调用: Left?.Generate(ref result, ref resultGiven); 当调用此Generate()函数6次时,我想调试程序并停止执行。如何操作?最简单的方法是使用全局变量 // somewhere before Generate first call var counter = 0; void Generate(ref result, ref resultGiven) { if (counter == 6) return; c

我的程序中有一个递归调用:

Left?.Generate(ref result, ref resultGiven);

当调用此
Generate()
函数6次时,我想调试程序并停止执行。如何操作?

最简单的方法是使用全局变量

// somewhere before Generate first call
var counter = 0;

void Generate(ref result, ref resultGiven)
{
  if (counter == 6)
     return;
  counter++;
  // the rest of function's body
} 

如果我理解正确,您希望限制递归的深度(即,不要让
生成
调用自身超过
6次)。如果是您的情况,您可以尝试以下课程:

using System.Diagnostics;

...

void Generate(ref result, ref resultGiven) {
  // --- Comment this out after debugging
  string currentFrame = new StackTrace(new StackFrame(false)).ToString().Trim();

  StackTrace trace = new StackTrace();

  int depth = trace
    .ToString()
    .Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
    .Where(frame => frame.Trim() == currentFrame)
    //.TakeWhile(frame => frame.Trim() == currentFrame) // if direct calls only
    .Count();

  // Prevent Generate to call itself more than 6 time 
  if (depth > 6) {
    // Maximum depth reached, return or launch debugger - Debugger.Launch()
    return;  
  }
  // --- Comment this out after debugging

  ...
}

使用计数或步长参数即可

Left?.Generate(ref result, ref resultGiven); // is same
这个函数看起来像这样:

void Generate(object ref result, object ref resultGiven, int step = 0)
{
  // do stuf

  // break for debug
  if (step >= 6)
  {
    return; 
  }
  // or only break when debugger is attached
  if (System.Diagnostics.Debugger.IsAttached && step >= 6)
  {
    return; 
  }
  // recursive
  Generate(ref result, ref resultGiven, step++);
}

添加计数器并在计数器达到6时退出?如果计数器=6,则使用Debugger.Launch();不只是不。不要在这么简单的事情上使用反射。这是反射的最邪恶和最亲切的用法!爱死它了@里夫内尔:没那么简单。如果使用不同的参数从例程的不同部分调用
Generate
,该怎么办?让我们恶化一下:同时来自不同的线程?这就是为什么要添加一个参数(默认值为0,例如:无需调整任何内容和线程安全)。为此使用反射就是使用大锤敲碎螺母。您正在限制对函数的任何调用:
Generate
的执行次数不能超过
6次。然而,OP似乎想要限制递归的深度(
Generate
不能调用自己超过
6次)。@DmitryBychenko,我不能确定,但主题的名称包括“中断程序”字样,所以我认为这两种情况之间没有区别。@DmitryBychenko,哦,我只是想到了“中断程序”可以表示不是“停止执行”,而是“创建断点”。当然,在这种情况下,您的方法更可取。这是不够的(在一般情况下):假设
Generate
调用方法
Foo
,该方法调用
Generate
。在您的方法中,我们也必须更改
Foo
。没错,但这不再是(严格地说)递归。