Me gustaría escribir una función reutilizable a la que pueda llamar dentro de cualquier método para registrar una instantánea de todas las variables locales. Por ejemplo:C# función reutilizable para volcar el valor actual de las variables locales
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);
}
me gustaría obtener una salida de la consola como esto:
step 1
Int32 a = 1
String s = something
step 2
Int32 a = 2
String s = something
String t = somethingelse
Quiero evitar proporcionar una lista específica de nombres de variables locales.
Lo más parecido que pude encontrar fue MethodInfo.GetCurrentMethod().GetMethodBody().LocalVariables
, pero no sé cómo acceder a los valores de las variables locales utilizando la reflexión.
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);
}
}
La API de reflexión parece adecuada para el análisis estático, pero no para un análisis dinámico como este. Por ejemplo, la variable t
no está dentro del alcance durante la primera llamada al dumpLocalVariables
, pero aún aparece en la propiedad LocalVariables
del MethodBody
.
Sospecho que hay una API de depuración que estoy pasando por alto. ¿Cómo completa Developer Studio la pestaña "locales" cuando está en un punto de interrupción? ¿Hay alguna manera de hacer algo similar en tiempo de ejecución?
EDIT:
que puedo ver en mi clase que ILSpy ejemplo utiliza códigos IL como ldloc.0 y ldloc.1 para llegar a la primera y segunda variable local.
.locals init (
[0] int32 a
[1] string s
[2] string t
)
y más tarde
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
Tal vez podría utilizar algún tipo de mecanismo de poder-como me permite hacer lo mismo? No me importa si la llamada a mi método reutilizable es desordenada, solo quiero algo que pueda pegar en cualquier bloque de código sin mucha edición manual.
"Sospecho que hay una API de depuración que se me escapa": 'System.Diagnostics.Debugger' –
@Henk: ¿se puede aclarar que ? No sabía que la clase 'Debugger' tenía nada útil que no fuera' IsAttached' y 'Break()'. – Groo
Posibles duplicados: [¿Hay alguna manera de examinar las variables de pila en tiempo de ejecución en C#?] (Http://stackoverflow.com/questions/5130414/is-there-a-way-to-examine-the-stack-variables -at-runtime-in-c), [C# Cómo volcar todas las variables y valores actuales durante el tiempo de ejecución] (http://stackoverflow.com/questions/1552478/c-how-to-dump-all-variables-current- valores durante el tiempo de ejecución). – Groo