我看到一些关于C#中缺少尾递归优化的问题,据说这使得该语言不适合实现递归算法。然而,这引出了一个问题,我们如何进行尾递归优化,同时在抛出异常或使用反射检查调用堆栈并对其采取行动时仍能提供有意义的堆栈跟踪。
我看到一些关于C#中缺少尾递归优化的问题,据说这使得该语言不适合实现递归算法。然而,这引出了一个问题,我们如何进行尾递归优化,同时在抛出异常或使用反射检查调用堆栈并对其采取行动时仍能提供有意义的堆栈跟踪。
如果您希望获得准确的堆栈跟踪,那么这很重要 :)
尾调用优化并不是唯一可能破坏堆栈跟踪的事情 - 最简单的例子就是内联,它肯定会影响到某些东西。基本上,任何依赖于准确堆栈跟踪的东西都是有风险的。
以下是一个非常简单的例子:
using System;
using System.Runtime.CompilerServices;
class Program
{
static void Main(string[] args)
{
try
{
Call1();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
}
}
static void Call1()
{
Call2();
}
static void Call2()
{
Call3();
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void Call3()
{
Call4();
}
static void Call4()
{
Call5();
}
static void Call5()
{
throw new Exception();
}
}
如果在不使用调试器的情况下构建和运行,则可能会出现以下情况:
at Program.Call3()
at Program.Main(String[] args)
基本上,要小心处理堆栈跟踪。