首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在.NET中从堆栈帧获取参数值?

在.NET中从堆栈帧获取参数值?
EN

Stack Overflow用户
提问于 2008-09-17 01:54:56
回答 2查看 8.2K关注 0票数 19

我希望能够从.NET的堆栈框架中获得所有参数值,就像在Visual Studio调试器中查看调用堆栈中的值一样。我的方法主要集中在使用StackFrame class,然后在ParameterInfo数组上进行反映。我已经在反射和属性方面取得了成功,但事实证明这有点棘手。

有没有实现这一点的方法?

到目前为止,代码如下所示:

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        a.Go(1);
    }
}

public class A
{
    internal void Go(int x)
    {
        B b = new B();
        b.Go(4);
    }
}

public class B
{
    internal void Go(int y)
    {
        Console.WriteLine(GetStackTrace());

    }
    public static string GetStackTrace()
    {
        StringBuilder sb = new StringBuilder();
        StackTrace st = new StackTrace(true);
        StackFrame[] frames = st.GetFrames();

        foreach (StackFrame frame in frames)
        {
            MethodBase method = frame.GetMethod();

            sb.AppendFormat("{0} - {1}",method.DeclaringType, method.Name);
            ParameterInfo[] paramaters = method.GetParameters();
            foreach (ParameterInfo paramater in paramaters)
            {
                sb.AppendFormat("{0}: {1}", paramater.Name, paramater.ToString());
            }
            sb.AppendLine();
        }
        return sb.ToString();
    }
}

输出如下所示:

代码语言:javascript
复制
SfApp.B - GetStackTrace
SfApp.B - Go
y: Int32 y
SfApp.A - Go
x: Int32 x
SfApp.Program - Main
args: System.String[] args

我希望它看起来更像这样:

代码语言:javascript
复制
SfApp.B - GetStackTrace
SfApp.B - Go
y: 4
SfApp.A - Go
x: 1
SfApp.Program - Main

为了提供一点背景,我的计划是在抛出自己的异常时尝试使用它。我会更详细地研究你的建议,看看是否合适。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2008-09-16 18:13:42

似乎不能这样做。它将只提供有关该方法及其参数的元信息。而不是调用堆栈时的实际值。

有些人建议从ContextBoundObject派生类,并使用IMessageSink通知所有方法调用和参数值。这通常用于.NET Remoting

另一个建议可能是编写调试器。这就是IDE获取信息的方式。微软有Mdbg,你可以找到它的源代码。或者编写一个CLR profiler

票数 8
EN

Stack Overflow用户

发布于 2022-01-02 01:27:11

我很确定这是可能的,但我不能给你你想要的答案。我建议了一种不同的方法,虽然灵活性较低,但如果您预先有堆栈跟踪,并且希望看到传递到每个帧的参数,则此方法仍然有用。

通常,您会在堆栈跟踪中出现的每个方法的开头分散日志消息,但这是相当麻烦的,而且并不总是可能的:如果您调用外部库中定义的方法怎么办?

当我在寻找如何解决这个问题的灵感时,我发现了一个名为Harmony的库,它允许您在运行时修补方法。基本上,一个方法可以用前缀、后缀和/或终结器来装饰。文档中对此进行了很好的解释,但为了提供堆栈跟踪中方法的详细信息,您可以使用的想法是创建一个打印每个帧的参数的prefix

不幸的是,仅使用Harmony,我不认为可以像您希望的那样对当前StackTrace中的方法执行此操作,即使使用后缀/终结器也是如此。但是,它可以在调用目标方法之前完成。

我已经创建了一个非常简单的库,叫做DebugLogger,它在内部使用Harmony,这简化了这个过程。Here是存储库,但您也可以在Nuget上找到它:

代码语言:javascript
复制
dotnet add package DebugLogger --version 1.0.0

它仍然有很多局限性,部分原因是Harmony,它只有一堆测试,还没有准备好被认为是一个库,但在我看来,它是一个很好的起点。我准备了一个演示DebugLogger初始化的Fiddle和几个虚拟类,以使演示变得“有意义”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/75076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档