从方法内检索调用方法名称

我在一个对象中有一个方法,它是从该对象中的许多位置调用的。有没有一种快速简单的方法来获得调用这个流行方法的方法的名称。

伪代码示例:

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类,但是我真的不喜欢每次调用该方法时都运行整个堆栈跟踪。

84156 次浏览

其实很简单。

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();
}

我不认为不跟踪堆栈就可以完成这项工作,但是,这项工作相当简单:

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

然而,我认为你真的应该停下来问问你自己这是否是必要的。

只要传入一个参数

public void PopularMethod(object sender)
{


}

IMO: 如果它足够好的事件,它应该是足够好的这一点。

我认为你确实需要使用 StackTrace类,然后在下一帧 StackFrame.GetMethod()

不过,使用 Reflection做这件事似乎有点奇怪。如果您正在定义 PopularMethod,则不能定义参数或其他东西来传递您真正需要的信息。(或者放在一个基础类或者别的什么...)

虽然您可以很明确地跟踪 Stack 并以这种方式找到它,但我还是希望您重新考虑一下您的设计。如果您的方法需要了解某种类型的“状态”,我建议您只需创建一个枚举或类似的东西,并将其作为 PopularMethod ()的一个参数。差不多吧。根据你发布的内容,追踪那个堆栈太过分了。

我经常发现自己想这样做,但最终总是重构我的系统设计,所以我不会得到这种“摇尾巴的狗”反模式。其结果总是一个更加健壮的架构。

在.NET 4.5/C # 5中,这很简单:

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

编译器会自动添加呼叫者的名字; 因此:

void Foo() {
PopularMethod();
}

将通过 "Foo"