2009-06-11 10 views
4

C#では、クラスまたはメソッドが誰(つまりどのクラス/メソッド)を呼び出したかを知る方法はありますか?どのクラスがメソッドを呼び出すかを調べる

例えば、私が持っているかもしれません

class a{ 
    public void test(){ 
     b temp = new b(); 
     string output = temp.run(); 
    } 
} 

class b{ 
    public string run(){ 
     **CODE HERE** 
    } 
} 

出力: " '' クラスの '試験' の方法によって呼び出されます。"

+1

この電源は悪くなく良いものを使用してください。 –

答えて

13

たStackFrame

var frame = new StackFrame(1); 

Console.WriteLine("Called by method '{0}' of class '{1}'", 
    frame.GetMethod(), 
    frame.GetMethod().DeclaringType.Name); 
+1

ええ、これはちょうど解決策のようです。ちょうど明確にするために、 'new StackFrame(1)'は現在の(アクティブな)フレームから1つ上のレベルでスタックフレームを返します。 – Noldorin

+0

素敵なオーバーロードを知らなかった... +1 –

2

スタックトレースを見て、誰が呼び出すのかを判断できます。

http://msdn.microsoft.com/en-us/library/system.environment.stacktrace.aspx

+2

StackTraceは完全なスタックトレースを保証するものではなく、近似値のみを提供します。詳細は、http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace.aspxの「備考」を参照してください。また、NoInlining属性があなたに役立たない例については、http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspxを参照してください。特定の最適化が32ビットモードではなく64ビットモードで行われるという事実は、JITterの実装の詳細であり、警告なしで変更される可能性があります。 – Levi

+0

それは実際にはかなり面白いです。 私は、関数を呼び出すクラスを知る必要がある理由は、デバッグのためだけであると仮定しています。これはおそらく便利です。しかし、これはアプリケーションロジックのために使用されている場合は、ええ、その悪い考え方は、パフォーマンスのためにとにかく。 – Nippysaurus

0

ジミーが示唆しているように、StackFrameが行います。ただし、StackFrameを使用するときは注意してください。それをインスタンス化するのはかなりコストがかかります。インスタンス化する場所に応じて、MethodImplOptions.NoInliningを指定する必要があります。呼び出し側の呼び出し元を見つけるためにスタックウォークを折り返したい場合は、次のようにする必要があります。

[MethodImpl(MethodImplOptions.NoInlining)] 
public static MethodBase GetThisCaller() 
{ 
    StackFrame frame = StackFrame(2); // Get caller of the method you want 
             // the caller for, not the immediate caller 
    MethodBase method = frame.GetMethod(); 
    return method; 
} 
関連する問題