web-dev-qa-db-ja.com

現在のメソッドの名前をコードから取得する方法

私はあなたができることを知っています

this.GetType().FullName

取得するため

My.Current.Class

しかし、私は何を得るために呼び出すことができます

My.Current.Class.CurrentMethod
333
Nick Allen
using System.Diagnostics;
...

var st = new StackTrace();
var sf = st.GetFrame(0);

var currentMethodName = sf.GetMethod();

あるいは、ヘルパーメソッドが必要な場合は、

[MethodImpl(MethodImplOptions.NoInlining)]
public string GetCurrentMethod()
{
    var st = new StackTrace();
    var sf = st.GetFrame(1);

    return sf.GetMethod().Name;
}

@stusmithへのクレジットで更新されました。

324
user151323

メソッド内からSystem.Reflection.MethodBase.GetCurrentMethod().Nameを呼び出します。

474
Jamie Ide

反射は木のために森を隠すためのコツがあります。現在のメソッド名を正確かつ迅速に取得することに問題はありません。

void MyMethod() {
  string currentMethodName = "MyMethod";
  //etc...
}

リファクタリングツールはおそらくそれを自動的に修正しませんが。

Reflectionを使用することによる(かなりの)コストをまったく気にしないのであれば、このヘルパーメソッドは役に立ちます。

using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Reflection;
//...

[MethodImpl(MethodImplOptions.NoInlining)]
public static string GetMyMethodName() {
  var st = new StackTrace(new StackFrame(1));
  return st.GetFrame(0).GetMethod().Name;
} 

更新:C#バージョン5と.NET 4.5は、この一般的な必要性に対する最善の解決策を持っています。 [CallerMemberName]属性 を使ってコンパイラを自動化することができます呼び出しメソッドの名前を文字列引数で生成します。その他の便利な属性としては、コンパイラにソースコードファイルのパスを生成させる[CallerFilePath]や、呼び出しを行ったステートメントのソースコードファイル内の行番号を取得する[CallerLineNumber]があります。


Update2:答えの冒頭で私が提案した構文は、気の利いたリファクタリングツールなしでC#バージョン6で動作するように作られることができます:

string currentMethodName = nameof(MyMethod);
93
Hans Passant

私はフルネームをつけるための最善の方法だと思います:

 this.GetType().FullName + "." + System.Reflection.MethodBase.GetCurrentMethod().Name;

またはこれを試してください

string method = string.Format("{0}.{1}", MethodBase.GetCurrentMethod().DeclaringType.FullName, MethodBase.GetCurrentMethod().Name);   
31
Zakaria

これはうまくいきませんか?

System.Reflection.MethodBase.GetCurrentMethod()

現在実行中のメソッドを表すMethodBaseオブジェクトを返します。

名前空間:System.Reflection

アセンブリ:mscorlib(mscorlib.dll内)

http://msdn.Microsoft.com/ja-jp/library/system.reflection.methodbase.getcurrentmethod.aspx

10
Orwellophile

MethodBase.GetCurrentMethod()を使用することもできます。これは、JITコンパイラーがそれが使用されている場所でメソッドをインライン化することを禁止します。


更新:

このメソッドには特別な列挙体StackCrawlMarkが含まれています。これは、私の理解では現在のメソッドをインライン化しないようにJITコンパイラに指定するものです。

これはSSCLIに存在する列挙に関連したコメントの私の解釈です。コメントは続きます:

// declaring a local var of this enum type and passing it by ref into a function 
// that needs to do a stack crawl will both prevent inlining of the calle and 
// pass an ESP point to stack crawl to
// 
// Declaring these in EH clauses is illegal; 
// they must declared in the main method body
9
João Angelo

System.Reflection.MethodBase.GetCurrentMethod().Nameはあまり良い選択ではありません '追加情報なしでメソッド名を表示するだけなので。

string MyMethod(string str)と同様に、上記のプロパティはMyMethodのみを返しますが、これはほとんど適切ではありません。

メソッドのシグネチャ全体を返すSystem.Reflection.MethodBase.GetCurrentMethod().ToString()を使うのが良いでしょう...

5
Arefin

これをチェックしてください。 http://www.codeproject.com/KB/dotnet/MethodName.aspx

3
Brian Mains