web-dev-qa-db-ja.com

メソッド内から呼び出し元のメソッド名を取得する

可能性のある複製:
現在のメソッドを呼び出したメソッドを見つけるにはどうすればよいですか?

オブジェクト内のいくつかの場所から呼び出されるメソッドがオブジェクトにあります。この人気のあるメソッドを呼び出したメソッドの名前をすばやく簡単に取得する方法はありますか。

擬似コードの例:

_public Main()
{
     PopularMethod();
}

public ButtonClick(object sender, EventArgs e)
{
     PopularMethod();
}

public Button2Click(object sender, EventArgs e)
{
     PopularMethod();
}

public void PopularMethod()
{
     //Get calling method name
}
_

PopularMethod()内で、Mainから呼び出された場合、Mainの値を確認したい...「ButtonClick」を表示したいPopularMethod()ButtonClickから呼び出された場合

私はSystem.Reflection.MethodBase.GetCurrentMethod()を見ていましたが、それでは呼び出しメソッドを取得できません。私はStackTraceクラスを見てきましたが、そのメソッドが呼び出されるたびにスタックトレース全体を実行するのは本当に楽しみではありませんでした。

55
Scott Vercuski

スタックをトレースせずにできるとは思いません。ただし、それは非常に簡単です。

StackTrace stackTrace = new StackTrace();
MethodBase methodBase = stackTrace.GetFrame(1).GetMethod();
Console.WriteLine(methodBase.Name); // e.g.

しかし、私はあなたが本当に停止し、これが必要かどうか自問する必要があると思います。

71
jason

.NET 4.5/C#5では、これは簡単です。

public void PopularMethod([CallerMemberName] string caller = null)
{
     // look at caller
}

コンパイラは、呼び出し元の名前を自動的に追加します。そう:

void Foo() {
    PopularMethod();
}

"Foo"

147
Marc Gravell

これは実際には非常に簡単です。

public void PopularMethod()
{
    var currentMethod = System.Reflection.MethodInfo
        .GetCurrentMethod(); // as MethodBase
}

しかし、注意してください、メソッドのインライン化が効果を発揮するかどうかは少し懐疑的です。これを行うと、JITコンパイラーが邪魔にならないようにすることができます。

[System.Runtime.CompilerServices.MethodImpl(
 System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
public void PopularMethod()
{
    var currentMethod = System.Reflection.MethodInfo
        .GetCurrentMethod();
}

呼び出しメソッドを取得するには:

[System.Runtime.CompilerServices.MethodImpl(
 System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
public void PopularMethod()
{
    // 1 == skip frames, false = no file info
    var callingMethod = new System.Diagnostics.StackTrace(1, false)
         .GetFrame(0).GetMethod();
}
16
John Leidegren

パラメータを渡すだけです

public void PopularMethod(object sender)
{

}

IMO:イベントに十分であれば、これにも十分なはずです。

5
Sruly

私は自分がこれをやりたいと思うことがよくありますが、システムの設計を常にリファクタリングしているため、この「犬を振る尾」アンチパターンを取得できません。その結果、常により堅牢なアーキテクチャが実現されています。

4
JonPen

ほとんどの場合、スタックをトレースしてその方法を理解することができますが、デザインを再考することをお勧めします。メソッドが何らかの「状態」について知る必要がある場合は、enumまたは何かを作成し、それをPopularMethod()のパラメーターとして取得するだけです。それらの線に沿って何か。投稿内容に基づいて、スタックをトレースするとIMOが過剰になります。

1
BFree

次のフレームでStackTraceクラスを使用してからStackFrame.GetMethod()を使用する必要があると思います。

ただし、これはReflectionを使用するのは奇妙なことのようです。 PopularMethodを定義している場合、本当に必要な情報を渡すためのパラメーターや何かを定義することはできません。 (または、基本クラスなどに配置します...)

0
C. Dragon 76