我想寫一個可以在任何方法中調用的可重用函數來記錄所有局部變量的快照。例如:C#可轉儲函數轉儲當地變量的當前值
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似乎非常適合靜態分析,但不適用於像這樣的動態分析。例如,在首次致電dumpLocalVariables
期間,變量t
不在範圍內,但它仍出現在MethodBody
的LocalVariables
屬性中。
我懷疑有一個調試API,我忽略了。 Developer Studio如何在斷點處填充「本地」選項卡?有沒有辦法在運行時做類似的事情?
編輯:
我可以在我的例子類使用像ldloc.0和ldloc.1 IL代碼去的第一和第二局部變量ILSpy看到。
.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
也許我可以用某種代理樣的機制,讓我做同樣的事情?我不介意如果對我的可重用方法的調用是混亂的,我只想要一些我可以粘貼到任何代碼塊而不需要很多手動編輯的東西。
部分「我懷疑的是,我可以俯瞰調試API」:'System.Diagnostics.Debugger' – 2011-05-08 18:34:10
@Henk:你可以澄清?我不知道'Debugger'類除了'IsAttached'和'Break()'以外還有其他用處。 – Groo 2011-05-08 18:44:19
可能的重複:[有沒有辦法在c#中的運行時檢查堆棧變量?](http://stackoverflow.com/questions/5130414/is-there-a-way-to-examine-the-stack-variables在運行時在C),[C#如何在運行時轉儲所有變量和當前值](http://stackoverflow.com/questions/1552478/c-how-to-dump-all-variables-current-值-期間的運行時)。 – Groo 2011-05-08 18:49:39