C#可重复使用的功能倾倒局部变量的当前值 [英] C# reusable function to dump current value of local variables

查看:231
本文介绍了C#可重复使用的功能倾倒局部变量的当前值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个可重用的功能,我可以在任何方法中调用记录所有局部变量的快照。例如:

I would like to write a reusable function I can call within any method to log a snapshot of all the local variables. For example:

    void somemethod()
    {
        int a = 1;
        string s = "something";
        dumpLocalVariables("step 1", MethodInfo.GetCurrentMethod(), this);

        a++;
        string t = s + "else";
        dumpLocalVariables("step 2", MethodInfo.GetCurrentMethod(), this);
    }



我想获得这样的控制台输出:

I would like to get a console output like this:

step 1
    Int32 a = 1 
    String s = something
step 2
    Int32 a = 2
    String s = something
    String t = somethingelse

我想避免提供本地变量名称的具体名单。

I want to avoid providing a specific list of local variable names.

我能找到的是 MethodInfo.GetCurrentMethod()。GetMethodBody()。LocalVariables ,但我不知道如何访问使用反射局部变量的值。

The closest I could find was MethodInfo.GetCurrentMethod().GetMethodBody().LocalVariables, but I do not know how to access the values of the local variables using reflection.

void dumpLocalVariables(string context, MethodBase currentMethod, object obj)
{
    Console.WriteLine(context);
    MethodBody methodBody = currentMethod.GetMethodBody();
    foreach (LocalVariableInfo lvi in methodBody.LocalVariables)
    {
        string variableType = lvi.LocalType.Name;
        // how do I get this?
        string variableName = "variableNameHere";
        // how do I get this?    
        string variableValue = "variableValueHere";
        Console.WriteLine("   " + variableType  + " " + variableName + 
            " = " + variableValue);
    }
}



反射API似乎非常适合用于静态分析,但不是这样的动态分析。例如,变量 T 不在范围内第一次调用 dumpLocalVariables 中,但它仍然出现在 LocalVariables MethodBody

The reflection API seems well suited for static analysis, but not for dynamic analysis like this. For instance, the variable t is not in scope during the first call to dumpLocalVariables, but it still appears in the LocalVariables property of the MethodBody.

我怀疑有,我俯瞰调试API。如何开发工作室填充时,当地人标签断点? ?有没有办法做到在运行时类似的事情

I suspect there is a debugging API that I am overlooking. How does Developer Studio populate the "locals" tab when at a breakpoint? Is there a way to do something similar at runtime?

编辑:

我可以ILSpy看到我例如类使用的IL代码像ldloc.0和ldloc.1到达所述第一和第二局部变量。

I can see in ILSpy that my example class uses IL codes like ldloc.0 and ldloc.1 to get to the first and second local variable.

.locals init (
    [0] int32 a
    [1] string s
    [2] string t
)

和后来

IL_001b: ldloc.0  // this is a
IL_001c: ldc.i4.1
IL_001d: add
IL_001e: stloc.0
IL_001f: ldloc.1  // this is s
IL_0020: ldstr "else"
IL_0025: call string string::Concat(string, string)
IL_002a: stloc.2  // this is t

也许我可以使用某种代理样的机制,让我做同样的事?我不介意调用我的可重复使用的方法是凌乱的,我只是想要的东西,我可以粘贴到没有大量的手工编辑的代码块。

Maybe I could use some sort of proxy-like mechanism that lets me do the same thing? I don't mind if the call to my reusable method is messy, I just want something I can paste into any code block without a lot of hand-editing.

推荐答案

请参阅此相关的问题:

是否有一个简单的方法来获得在C#中的当前栈帧的所有局部变量(或CIL )

简短的回答是:因为他们是在堆栈上运行时直接分配你不能让局部变量的值,从而并非通过反射提供。要做到这一点的唯一方法是通过调试器API ...它从琐碎的远。此外,如果您的自定义调试器实际上是附着在这个过程只会工作。

The short answer is: you can't get the values of the local variables because they're allocated directly on the stack at runtime, and thus are not available via reflection. The only way to do this is via the debugger API...and it's far from trivial. Further, this would only work if your custom debugger is actually attached to the process.

有一个更好,更可行的方法可能是通过装配编织。你说你不希望有方法都记录它们的值时,就知道局部变量的具体名称访问。我建议建立两种方法:

A better, more feasible option might be via assembly weaving. You said you don't want to have the method have to know the specific names of local variables to access when logging their values. I would suggest creating two methods:

static void LogVariables();

static void LogVariables(params string[] names, params object[] values);



添加一个调用的程序集织造例程交换出第一LogVariables与第二调用后生成任务,但明确规定变量名称/值的方法。你可以写这个程序来修改使用单丝丝的组件(也有其他工具也可以做到这一点)

Add a post build task that calls an assembly weaving routine that swaps out the first LogVariables call with the second, but explicitly providing the variable names/values to the method. You can write this routine to modify the assembly using Mono Cecil (there are other tools too that can do this).

http://www.mono-project.com/Cecil

这篇关于C#可重复使用的功能倾倒局部变量的当前值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆