我想编写一个可以在任何方法中调用的可重用函数来记录所有局部变量的快照。例如:
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);
}
我想得到这样的控制台输出:
step 1
Int32 a = 1
String s = something
step 2
Int32 a = 2
String s = something
String t = somethingelse
我想避免提供特定的局部变量名称列表。
我能找到的最接近的是MethodInfo.GetCurrentMethod().GetMethodBody().LocalVariables
,但我不知道如何使用反射访问局部变量的值。
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
.
我怀疑我忽略了一个调试 API。Developer Studio 在断点时如何填充“本地”选项卡?有没有办法在运行时做类似的事情?
编辑:
我可以在 ILSpy 中看到我的示例类使用像 ldloc.0 和 ldloc.1 这样的 IL 代码来获取第一个和第二个局部变量。
.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
也许我可以使用某种类似代理的机制来让我做同样的事情?我不介意对我的可重用方法的调用是否混乱,我只想要一些可以粘贴到任何代码块中而无需大量手动编辑的东西。