2012-06-30 18 views
5

.NET 4.5にはという新しい属性があります。[CallerMemberNameAttribute]メソッドのパラメータにアタッチすると、というメソッドの文字列名が提供されます。そのメソッド(それが理にかなっている場合)。C#スタックトレースを使用しない呼び出しメソッドの取得

しかし、残念ながら(私はXNAで何かを作りたいので)私は.NET 4.0をターゲットにしています。

私のような何かを行うことができるようにしたい:

私の出力は MethodAだろう
void MethodA() { 
    MethodB(); 
} 

void MethodB() { 
    string callingMethodName = (...?); 
    Console.WriteLine(callingMethodName); 
} 

を。

は、私は、スタックトレースを経由してこれを行うことができます知っているが、それは)信頼できないですし、その情報を収集するために、他の方法があるかどうb)のSloooowは... は、だから私は...しかし、それはすることができ、

を思ったんだけど

私は誰でも問題に抱いている可能性のあるアイデアや知識を期待していました。おかげで事前に:)

+3

呼び出し元のメソッド名を文字列として渡しますか? – Oded

+2

@Odedよくわかりますが、明らかに私はMethodB( "MethodA")を呼び出すことができますが、ポイントは私が動的にそれをやろうとしているので、MethodAをMethodCに変更してもその呼び出しを編集する必要はありません。 – Xenoprimate

+0

あなたはその点を問題にしていませんでした。 – Oded

答えて

13

CallerMemberNameAttributeをコンパイルするためにVisual Studio 2012を使用し、.NET 4.0または3.5をターゲットにしている場合でも.NET 4.5と同じ方法で使用できます。コンパイラはコンパイル時にも置換を実行しますが、古いフレームワークバージョンを対象にしています。

ちょうどトリックを行いますプロジェクトに以下の追加:

namespace System.Runtime.CompilerServices 
{ 
    public sealed class CallerMemberNameAttribute : Attribute { } 
} 
+0

私は趣味のプログラマーですので、これは愚かな質問ですが、申し訳ありませんが、私はMicrosoftのCallerMemberNameAttributeのソースを見ることができる方法はありますか?それをコピーするには、私は意味します。 – Xenoprimate

+2

一般に、はい、ILSpyを使用して.NETライブラリを逆コンパイルできます。 http://wiki.sharpdevelop.net/ILSpy.ashxしかし、興味深いビットは他のコードでどのように使われているかという点で、属性は興味深いものがほとんどありません。例えば。 @ReedCopseyの記述から、コンパイル時には属性自体ではなくコンパイル時に変換が行われるため、.NET 4.5ランタイムは必要ないため、興味深いコードは見当たりません。 –

+0

ああ、コンパイラは「CallerMemberNameAttribute」という名前を見て、独自のロジックを挿入します。もしそうなら、私はその名前の空白の属性を作成することができます。 – Xenoprimate

0

あなたは、呼び出されたメソッドのパラメータとして、発信者の名前を供給することができます。ない非常に何を求めているが、それはスタックフレームにアクセスしなくても動作します:MethodBase.GetCurrentMethod()を使用することにより

[MethodImpl(MethodImplOptions.NoInlining)] 
void MethodA() 
{ 
    string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name; 
    MethodB(methodName); 
} 

void MethodB(string callingMethodName) 
{ 
    Console.WriteLine(callingMethodName); 
} 

を、あなたの実装がリファクタリングセーフままであることを保証することができます - あなたの方法の変更の名前ならば、結果はまだ正しいでしょう。

メソッドのインライン展開を避けるため、呼び出し方法をMethodImplOptions.NoInliningとマークすることを忘れないでください。

関連する問題