すべてのローカル変数のスナップショットをログに記録するために、任意のメソッド内で呼び出すことができる再利用可能な関数を作成したいと考えています。例えば:
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 は、ブレークポイントで「ローカル」タブをどのように設定しますか? 実行時に似たようなことをする方法はありますか?
編集:
サンプル クラスが ldloc.0 や ldloc.1 などの IL コードを使用して、1 番目と 2 番目のローカル変数を取得していることを 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
たぶん、同じことを可能にするある種のプロキシのようなメカニズムを使用できますか? 再利用可能なメソッドの呼び出しが乱雑であってもかまいません。手で編集することなく、任意のコード ブロックに貼り付けることができるものが欲しいだけです。