Я хотел бы написать функцию многократного использования, которую я могу вызвать в любом методе, чтобы записать снимок всех локальных переменных.Например:
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 заполняет вкладку «locals» в точке останова?Есть ли способ сделать что-то подобное во время выполнения?
EDIT:
Я вижу в 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
Может быть, я мог бы использовать какой-то прокси-подобный механизм, который позволяет мне делать то же самое?Я не возражаю, если вызов моего метода многократного использования является грязным, я просто хочу что-то, что я могу вставить в любой блок кода без большого количества ручного редактирования.