Я хотел бы написать повторно используемую функцию, которую я могу вызывать в любом методе для регистрации моментального снимка всех локальных переменных. Например:
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 я вижу, что мой класс-пример использует коды IL, такие как ldloc.0 и ldloc.1, для доступа к первой и второй локальной переменной.
.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
Может быть, я мог бы использовать какой-то прокси-подобный механизм, который позволяет мне делать то же самое? Я не возражаю, если вызов моего повторно используемого метода будет грязным, я просто хочу что-то, что я могу вставить в любой блок кода без большого ручного редактирования.
System.Diagnostics.Debugger
- person Henk Holterman   schedule 08.05.2011Debugger
есть что-то полезное, кромеIsAttached
иBreak()
. - person Groo   schedule 08.05.2011System.Diagnostics.Debugger
не предлагает ничего, что могло бы помочь в этом случае. - person casperOne   schedule 08.05.2011