5

I've noticed that .NET 4.5 has a new attribute called [CallerMemberNameAttribute] which, when attached to a parameter of a method, will supply the string name of the method that called that method (if that makes sense).

However, unfortunately (because I want to make something with XNA) I'm only targeting .NET 4.0.

I want to be able to do something like:

void MethodA() {
   MethodB();
}

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

Where my output would be MethodA.

I know I could do this via stack trace, but that's a) Unreliable and b) Sloooow... So I'm wondering if there's any other way to glean that information, however that may be...

I was hoping for any ideas or knowledge that anyone might have on the issue. Thanks in advance :)

4

2 回答 2

13

如果您使用 Visual Studio 2012 编译它,您可以编写自己的代码CallerMemberNameAttribute并以与 .NET 4.5 相同的方式使用它,即使您仍然以 .NET 4.0 或 3.5 为目标。编译器仍将在编译时执行替换,即使针对较旧的框架版本。

只需将以下内容添加到您的项目中即可:

namespace System.Runtime.CompilerServices
{
    public sealed class CallerMemberNameAttribute : Attribute { }
}
于 2012-06-30T20:24:28.380 回答
0

您可以提供调用方名称作为被调用方法的参数。不完全符合您的要求,但它无需访问堆栈框架即可工作:

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

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

通过使用MethodBase.GetCurrentMethod(),您可以确保您的实现保持重构安全——如果您的方法名称更改,结果仍然是正确的。

不要忘记标记您的调用方法,MethodImplOptions.NoInlining以避免方法内联。

于 2012-06-30T20:52:05.527 回答