Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以在C#调用堆栈中删除或插入帧?_C#_Callstack - Fatal编程技术网

是否可以在C#调用堆栈中删除或插入帧?

是否可以在C#调用堆栈中删除或插入帧?,c#,callstack,C#,Callstack,使用StackTrace我可以得到堆栈帧。我的问题是是否可以在C#中操纵调用堆栈?更具体地说:有没有可能 要在调用堆栈中插入帧?或 要从中删除帧吗 StackTrace类不支持此类操作。根据msdn,帧是只读的(只有GetFrame、GetFrames方法可用) 要查看该类是如何由框架创建的,您可以直接查看该类的源代码。堆栈是程序运行时的一个非常内部的组件。有能力改变它将有可能: 做几乎不受限制的转到。这被认为是一种非常糟糕的编程实践,甚至在PHP中也不可能实现。调试这样的东西将是一团混乱

使用
StackTrace
我可以得到堆栈帧。我的问题是是否可以在C#中操纵调用堆栈?更具体地说:有没有可能

  • 要在调用堆栈中插入帧?或

  • 要从中删除帧吗


StackTrace类不支持此类操作。根据msdn,帧是只读的(只有GetFrame、GetFrames方法可用)


要查看该类是如何由框架创建的,您可以直接查看该类的源代码。

堆栈是程序运行时的一个非常内部的组件。有能力改变它将有可能:

  • 做几乎不受限制的转到。这被认为是一种非常糟糕的编程实践,甚至在PHP中也不可能实现。调试这样的东西将是一团混乱
  • 在方法返回时注入代码。这可能很有用,但面向方面的工具已经涵盖了这一点,如PostSharpSpring.NET,它们允许您以清晰和可预测的方式完成这一工作。它们覆盖的情况远远不止方法返回
因此,我不认为有任何编程语言允许您显式地操作堆栈。它会使事情变得非常混乱,并且它可能产生的任何好处都已经包含在面向方面的编程中。我打赌AOP会让你实现你想要的。

不,这是不可能的。 此外,操作堆栈的能力将带来许多安全性/一致性问题。这就是为什么操纵堆栈是一种不好的做法/一种安全缺陷,即使您可以这样做(例如,在C中)。例如,臭名昭著的“缓冲区溢出”类安全问题正是源于此:能够在代码中插入一个“goto”(一个新的堆栈帧),以便在返回时执行恶意负载,而不是合法的调用函数


但是,你为什么要这么做呢?如果有一个真正的目标,我们可以更好地说明如何做到这一点,并提出好的替代方案

在Smalltalk中操纵堆栈很容易,但我认为在C#中不可能做到。

是的,可以通过反射来实现。 归根结底,这是一根弦

下面是一个异常类,用于将Javascript堆栈跟踪记录为C#异常,
保留原始堆栈跟踪

using System.Reflection;
    public class JsException : Exception
    {
        static readonly FieldInfo _stackTraceString = typeof(Exception).GetField("_stackTraceString", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
        public JsException(string error, string stack)
            : base(error)
        {
            _stackTraceString.SetValue(this, stack);
        }
    }

请定义操作。你需要什么样的操作?检索?你说的“操纵”是什么意思?只有您通过说“Environment.StackTrace”或实际转移呼叫得到的输出?从任何托管代码内部,或通过自己托管CLR。请提供更多的上下文和您真正想要实现的内容。现在您已经编辑并添加了第二段,您的意思更清楚了,我投票支持重新打开。了解您为什么想要操纵调用堆栈会很有趣。这似乎是一个坏主意,它会使跟踪执行情况比以前使用Goto语句的情况更糟。您希望生成什么结果?我是说,好吧,你“操纵”调用堆栈做什么?更改执行点从函数返回的方式?或者你只是想改变StackTrace的显示方式?我同意,如果你需要编织,那么AOP就是OP应该寻找的。