65

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

伪代码示例:

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()我想看看Mainif it was called from Main... 我想看看 " ButtonClick" if PopularMethod()was called fromButtonClick

我在看,System.Reflection.MethodBase.GetCurrentMethod()但这不会让我得到调用方法。我看过这个StackTrace类,但我真的不喜欢每次调用该方法时都运行整个堆栈跟踪。

4

7 回答 7

184

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

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

编译器自动添加调用者的名字;所以:

void Foo() {
    PopularMethod();
}

将通过"Foo"

于 2013-01-02T13:08:21.680 回答
79

我认为不跟踪堆栈就无法完成。但是,这样做相当简单:

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

但是,我认为你真的必须停下来问问自己这是否有必要。

于 2009-03-05T18:29:32.637 回答
17

这实际上非常简单。

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();
}
于 2009-03-05T18:27:37.633 回答
5

只需传入一个参数

public void PopularMethod(object sender)
{

}

IMO:如果它对事件来说足够好,它应该足够好。

于 2009-03-05T18:30:12.307 回答
4

我经常发现自己想要这样做,但最终总是重构我的系统设计,所以我没有得到这种“摇尾巴”的反模式。结果始终是更强大的架构。

于 2012-07-25T12:16:35.323 回答
1

虽然您可以最明确地跟踪堆栈并以这种方式计算出来,但我会敦促您重新考虑您的设计。如果您的方法需要了解某种“状态”,我会说只需创建一个枚举或其他东西,并将其作为您的 PopularMethod() 的参数。类似的东西。根据您发布的内容,跟踪堆栈将是过度的 IMO。

于 2009-03-05T18:34:28.927 回答
0

我认为您确实需要使用该StackTrace课程,然后StackFrame.GetMethod()在下一帧上使用。

不过,这似乎是一件奇怪的事情Reflection。如果您正在定义PopularMethod,则无法定义参数或其他东西来传递您真正想要的信息。(或放入基类或其他东西......)

于 2009-03-05T18:34:24.920 回答