13

リフレクションを使用する場合、System.Diagnostics.StackTraceを使用してコールスタックを取得し(それを除けば、JIT最適化により大まかな概算になる可能性があります)、含まれているStackFrameオブジェクトを調べることができます。

スタックフレーム内のメソッドが実行されているオブジェクト(thisポインター)への参照を取得するにはどうすればよいですか?

スタックフレームオブジェクトでGetMethod()を呼び出すことでMethodBaseを取得できることはわかっていますが、探しているのはGetObject()に沿ったものです(メソッドが静的な場合は自然にnullを返します)。スタックフレームオブジェクトは、メソッド情報、元のファイルなどの静的に決定された情報に対してのみクエリできるようです。

VSデバッガーは、呼び出しスタックウィンドウ内の任意のスタックフレームをダブルクリックして、ローカルフィールドとクラスフィールドの値を確認できるため、(おそらく呼び出しスタックトレースを取得する別の方法を使用しますが)認識しています。

編集:明確にするために:メソッドが呼び出されたオブジェクトインスタンスが必要です。つまり、メソッドFoo()が呼び出しスタックのどこかでオブジェクトインスタンスAで呼び出され、スタックトレースを実行するメソッドにカスケードされる場合、スタックトレースを実行する場所からAへの参照を取得したいと思います。(メソッドベースの宣言タイプではありません)

4

3 に答える 3

7

これは不可能だと確信しています。理由は次のとおりです。

  1. 実行中の AppDomain\Thread や権限に関係なく、誰でもフレームを検索してオブジェクトを取得できるため、これによりタイプ セーフが破られる可能性があります。

  2. ' this' (C#) 識別子は実際にはインスタンス メソッド (最初のメソッド) への単なる引数であるため、実際には静的メソッドとインスタンス メソッドの間に違いはなく、コンパイラはその魔法を実行しthisてインスタンス メソッドに権利を渡します。もちろん、オブジェクトを取得するにはすべてのメソッド引数にアクセスする必要があることを意味しthisます。(これStackFrameはサポートしていません)

unsafeコードを使用してインスタンスメソッドへの最初の引数のポインターを取得し、それを正しい型にキャストすることで可能かもしれませんが、その方法については知識がなく、単なるアイデアです。

ところで、C# 3.0 拡張メソッドのようにコンパイルされた後のインスタンス メソッドを想像できthisます。最初の引数としてポインターを取得します。

于 2009-05-20T18:24:56.280 に答える
3

オブジェクトへの参照を取得することは可能thiscallですが、.NETコードのみを使用することはできません。ネイティブコードが含まれている必要があります。動的クラスとSystem.Relection.Emit名前空間を使用している場合でも、.NETには、別のメソッド評価スタックと引数にアクセスするための手段がありません。

一方、.NETメソッドを逆アセンブルすると、この参照が物理スタックにまったく渡されないことがわかります。代わりに、参照は(x64の場合)レジスタにThiscall格納されます。したがって、オブジェクトを取得するメソッドからメソッドへとスタックを登ることができます。次に、そのメソッドのマシンコード内で、レジスタECX(RCX)をスタックに保存する命令を検索し、その命令から、その参照が存在する相対アドレスを取得します。ECXRCXthiscall

もちろん、登山の方法はx32とx64のアプリケーションでは大きく異なります。このような関数を作成するには、C#だけでなくアセンブリコードも使用する必要があります。また、x64ではインラインアセンブラは使用できないことに注意してください。フルアセンブラモジュールである必要があります。

于 2012-05-10T08:56:25.467 に答える
-1

あなたが何を望んでいるかを完全に理解しているかどうかはわかりませんが、特定のスタックフレームのメソッドが宣言されている型を知りたい場合、このコードはそれを返すと思います:

StackTrace trace = new StackTrace();    
Type methodOwner = trace.GetFrame(0).GetMethod().DeclaringType;

もちろん、関心のあるフレームのインデックスを渡す必要があります (例として 0 を使用します)。

于 2009-05-20T18:05:45.417 に答える